IOS8 SplitVC + TabBarController + NavigationController
我正在做一个通用的应用程序使用大小类,我想在主/主视图中使用一个带有TabBarController的SplitView。在添加splitView之前一切正常,但现在应用程序崩溃(原因取决于视图的层次结构)。IOS8 SplitVC + TabBarController + NavigationController
所以我尝试了从Apple SplitView模板开始的相同的故事板,并在它的主视图上添加了一个TabBarController ...同样的问题。
层次 - 嵌入式主NavigationController在TabBarController: SplitVC(主)> TabBarController> NavigationController>的TableView SplitVC(详细信息)> NavigationController>查看
添加了此代码AppDelegate.m(如这里看到stackoverflow questions ios8-tabbarcontroller...防止正的DetailView模态呈现):
- (BOOL)splitViewController:(UISplitViewController *)splitViewController showDetailViewController:(UIViewController *)vc sender:(id)sender {
NSLog(@"UISplitViewController collapsed: %d", splitViewController.collapsed);
if ([[UIDevice currentDevice] userInterfaceIdiom] == UIUserInterfaceIdiomPhone)
{
if (splitViewController.collapsed) {
UITabBarController *master = (UITabBarController *) splitViewController.viewControllers[0];
UINavigationController *masterNavigationController = (UINavigationController *)master.selectedViewController;
UINavigationController *destinationNavigationController = (UINavigationController *)vc;
// push detail view on the navigation controller
[masterNavigationController pushViewController:[destinationNavigationController.viewControllers lastObject] animated:YES];
return YES;
}
}
return NO;
}
它工作正常...除非你在iPhone6加模拟,在这种情况下,在肖像开始,选择行后,如果您在景观旋转我看到的细节视图主要和次要观点。
如果不使用iPhone以纵向方向添加此代码,详细视图将以模态方式显示,当然,无需导航按钮。
编辑
不同的尝试后,并与一些外部的帮助我做了一些步骤了解决办法。
短版(见龙版就知道你为什么要这样做)
一个正确的解决问题的方法是继承TabBarController,并使其支持一些方法:
@implementation MyTabBarController
- (void)showViewController:(UIViewController *)vc sender:(id)sender
{
if ([self.selectedViewController isKindOfClass:UINavigationController.class])
[self.selectedViewController showViewController:vc sender:sender];
else
[super showViewController:vc sender:sender];
}
- (UIViewController*)separateSecondaryViewControllerForSplitViewController:(UISplitViewController *)splitViewController
{
return [self.selectedViewController separateSecondaryViewControllerForSplitViewController:splitViewController];
}
- (void)collapseSecondaryViewController:(UIViewController *)secondaryViewController forSplitViewController:(UISplitViewController *)splitViewController
{
[self.selectedViewController collapseSecondaryViewController:secondaryViewController forSplitViewController:splitViewController];
}
现在我有一个viewControllers堆栈的问题:与iPhone6Plus(唯一支持横向常规和紧凑的)应用程序崩溃,如果在横向,您更改选项卡,而不选择一行(因此detailView保持为前一个选项卡)然后以纵向旋转。
我知道我必须实现管理视图堆栈的分离和折叠方法,但我无法确定。有人可以帮忙吗?
龙版本(SplitViewController行为)
通常拆分视图控制器和导航控制器工作 在一起,以确保到-showDetailViewController呼叫:被包含在从一个视图控制器 :发送方在分割视图内 控制器导致新的详细视图控制器被推送到导航堆栈的 (当处于水平紧凑的环境中时)。至 做到这一点,UISplitViewController将覆盖 -showDetailViewController:sender:,如果水平压缩,则调用其主视图控制器的-showViewController:sender:方法。 UINavigationController覆盖-showViewController:sender:和 将传入视图控制器压入导航堆栈。
但是,UITabBarController并未覆盖 -showViewController:sender:因此它继承了以模态方式呈现传入视图控制器的默认实现。 要解决此问题,我必须继承UITabBarController并覆盖 -showViewController:sender:如果selectedViewController是导航 控制器,则转发到选项卡栏控制器的selectedViewController。
此外,当从一个紧凑 拆分视图控制器转换到水平尺寸类到常规水平尺寸类,分割 视图控制器首先发送 -splitViewController:separateSecondaryViewControllerFromPrimaryViewController: 消息给它的代理。委托人可以实现该方法,并且 自己处理分离,返回详细视图控制器。 如果委托没有实现此方法,或者如果 实现返回nil,则拆分视图控制器会将一个 -separateSecondaryViewControllerForSplitViewController:消息发送到其主视图控制器。主视图控制器应该执行 这种方法来处理分离。 UINavigationController执行 实现-separateSecondaryViewControllerForSplitViewController :. 它的实现弹出顶视图控制器关闭导航 堆栈并返回它。由于我使用标签栏控制器作为主视图控制器,我必须实现 -separateSecondaryViewControllerForSplitViewController:并自行处理分离。
另外我需要实现我自己的折叠逻辑。当控制器从常规水平尺寸级别转换为水平尺寸级别时,分割视图控制器首先发送一个 -splitViewController:collapseSecondaryViewController:onPrimaryViewController: 消息给其委托。代表可以实现此方法,并且 本身处理崩溃。如果委托人未实现此方法,则分割视图控制器会将其发送到其主视图控制器的一个 -collapseSecondaryViewController:forSplitViewController:消息。主视图控制器应该 实现此方法来处理分离。
UINavigationController确实实现了 -collapseSecondaryViewController:forSplitViewController :.它的实现将辅助视图控制器推到 导航堆栈上。由于我使用标签栏控制器作为主视图控制器,我必须实现 -collapseSecondaryViewController:forSplitViewController:并自行处理折叠。
所以,我发现东西的作品,即使是不规范的行为:
- (void)collapseSecondaryViewController:(UIViewController *)secondaryViewController forSplitViewController:(UISplitViewController *)splitViewController
{
[self.selectedViewController.navigationController collapseSecondaryViewController:secondaryViewController forSplitViewController:splitViewController];
}
这相当于在总回报YES
splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:
委托方法。像这样,你总是放弃辅助控制器。 希望这可以帮助某人。
试试这个片段并告诉我们你的结果。该片段从网站获得的StackOverflow外(Craig Marvelley)
#pragma mark - Split view
// Update secondaryview with the right screen
- (UIViewController *)splitViewController:(UISplitViewController *)splitViewController separateSecondaryViewControllerFromPrimaryViewController:(UIViewController *)primaryViewController {
int tryIt = 0;
if ((IS_IPHONE_6_PLUS) && (isLandscape)) {
if ([primaryViewController isKindOfClass:[UINavigationController class]]) {
for (UIViewController *controller in [(UINavigationController *)primaryViewController viewControllers]) {
tryIt = tryIt + 1;
if ([controller isKindOfClass:[UINavigationController class]] && ([[(UINavigationController *)controller visibleViewController] isKindOfClass:[yourPosibleScreen01 class]] || [[(UINavigationController *)controller visibleViewController] isKindOfClass:[yourPosibleScreen02 class]])) {
return controller;
}
// Sublevel where yo are to select the right screen. You must try with a number depends of how many internal hierarchy. But I believe you need number 2 but try it :)
if (tryIt > 2) {
return controller;
}
}
}
// Update detail screen
UIViewController *toViewController = [self.storyboard instantiateViewControllerWithIdentifier:@"YourScreenToShow"];
return toViewController;
}
return nil;
}
- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController {
return NO;
}
#pragma mark - Split view
它不起作用,同样的问题。你试过了吗?它适合你吗? – Zag
你好@扎格,对不起,但我忘记了一个关卡的柜台。我不知道为什么,但有时(在改变肖像到土地或反之后),我们有3个屏幕,而不仅仅是2个,我想是为了内部行动的顺序来屏幕。上面的代码适用于我。 – Beto
Hi @Beto,AFAIK SplitViewController层次结构根据折叠或分隔模式而变化。请参阅[本文](http://averagejake.com/post/104146203887/uisplitviewcontroller-adaptability-part-1)。我会尝试你的解决方案。谢谢。 – Zag