4

我正在做一个通用的应用程序使用大小类,我想在主/主视图中使用一个带有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:并自行处理折叠。

回答

0

所以,我发现东西的作品,即使是不规范的行为:

- (void)collapseSecondaryViewController:(UIViewController *)secondaryViewController forSplitViewController:(UISplitViewController *)splitViewController 
{ 
    [self.selectedViewController.navigationController collapseSecondaryViewController:secondaryViewController forSplitViewController:splitViewController]; 
} 

这相当于在总回报YESsplitViewController:collapseSecondaryViewController:ontoPrimaryViewController:委托方法。像这样,你总是放弃辅助控制器。 希望这可以帮助某人。

0

试试这个片段并告诉我们你的结果。该片段从网站获得的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 
+0

它不起作用,同样的问题。你试过了吗?它适合你吗? – Zag

+0

你好@扎格,对不起,但我忘记了一个关卡的柜台。我不知道为什么,但有时(在改变肖像到土地或反之后),我们有3个屏幕,而不仅仅是2个,我想是为了内部行动的顺序来屏幕。上面的代码适用于我。 – Beto

+0

Hi @Beto,AFAIK SplitViewController层次结构根据折叠或分隔模式而变化。请参阅[本文](http://averagejake.com/post/104146203887/uisplitviewcontroller-adaptability-part-1)。我会尝试你的解决方案。谢谢。 – Zag

相关问题