IOS8拆分vc+;TabBarController+;导航控制器

IOS8拆分vc+;TabBarController+;导航控制器,ios,objective-c,uitabbarcontroller,uisplitviewcontroller,adaptive-ui,Ios,Objective C,Uitabbarcontroller,Uisplitviewcontroller,Adaptive Ui,我正在使用大小类制作一个通用应用程序,我正在尝试在主/主视图中使用带有TabBarController的SplitView。在添加splitView之前,一切都很好,但现在应用程序崩溃了(原因取决于视图的层次结构) 所以我尝试了同样的故事板,从Apple SplitView模板开始,在其主/主视图上添加一个TabBarController。。。同样的问题 层次结构-TabBarController中的嵌入式主导航控制器: SplitVC(主)>TabBarController>Navigatio

我正在使用大小类制作一个通用应用程序,我正在尝试在主/主视图中使用带有TabBarController的SplitView。在添加splitView之前,一切都很好,但现在应用程序崩溃了(原因取决于视图的层次结构)

所以我尝试了同样的故事板,从Apple SplitView模板开始,在其主/主视图上添加一个TabBarController。。。同样的问题

层次结构-TabBarController中的嵌入式主导航控制器: SplitVC(主)>TabBarController>NavigationController>TableView SplitVC(详细信息)>导航控制器>视图

在AppDelegate.m中添加了此代码(如下所示,以防止以模式显示DetailView):

它很好用。。。除非在iPhone6 Plus中进行模拟,否则在这种情况下,从纵向开始并选择一行后,如果在横向旋转,我会将局部视图视为主视图和次视图

在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 stack有一个问题:对于iPhone6Plus(唯一一款同时支持水平常规和紧凑型),如果在横向中,您在不选择行的情况下更改选项卡(因此detailView仍然是上一个选项卡的选项卡),然后在纵向中旋转,则应用程序会崩溃

我知道我必须实现分离和折叠方法来正确管理视图堆栈,但我不知道如何实现。有人能帮忙吗

长版本(SplitViewController行为)

通常情况下,拆分视图控制器和导航控制器工作 共同确保对-showDetailViewController:sender的调用: 从包含在拆分视图中的视图控制器 控制器导致新的局部视图控制器被推送到 导航堆栈(在水平紧凑的环境中时)。到 如果执行此操作,UISplitViewController覆盖 -showDetailViewController:sender:如果水平压缩,则调用其主视图控制器的-showViewController:sender:方法。 UINavigationController覆盖-showViewController:发送方:和 将传入视图控制器推送到导航堆栈上

但是,UITabBarController不会覆盖 -showViewController:sender:因此它继承了默认实现,该实现以模态方式呈现传入的视图控制器。 为了解决这个问题,我必须将UITabBarController和override子类化 -showViewController:sender:如果selectedViewController是导航,则转发到选项卡栏控制器的selectedViewController 控制器

此外,当拆分视图控制器从精简视图过渡时 若要将水平尺寸类别转换为常规水平尺寸类别,请执行拆分 视图控制器首先发送一个 -splitViewController:separateSecondaryViewControllerFromPrimaryViewController: 向其代表发送消息。委托可以实现此方法并 处理分离本身,返回局部视图控制器。 如果委托未实现此方法,或者 实现返回nil,拆分视图控制器发送 -分离PLITVIEWCONTROLLER的第二个视图控制器:发送给其主视图控制器的消息。主视图控制器应实现 此方法用于处理分离。UINavigationController不执行此操作 implement-separateSecondaryViewControllerForSplitViewController:。 它的实现将俯视图控制器从导航中弹出 堆栈并返回它。因为我使用一个选项卡栏控制器作为 主视图控制器,我必须实现 -分离PLITVIEWCONTROLLER的二级视图控制器:并自行处理分离

我还需要实现我自己的崩溃逻辑。当分割视图 控制器从常规到水平大小的类转换为 压缩水平大小类,拆分视图控制器首先发送 -splitViewController:collapseSecondaryViewController:ontoPrimaryViewController: 向其代表发送消息。委托可以实现此方法并 自行处理塌陷。如果委托未实现此功能 方法时,拆分视图控制器将发送 -collapseSecondaryViewController:forSplitViewController:将消息发送到其主视图控制器。主视图控制器应 实现此方法来处理分离

UINavigationController不执行 -collapseSecondaryViewController:用于PLITVIEWController:。它的实现将次视图控制器推送到 导航堆栈。因为我使用一个选项卡栏控制器作为 主视图控制器,我必须实现 -collapseSecondaryViewController:forSplitViewController:并自行处理折叠


试试这个片段,告诉我们你的结果。此代码段来自stackOverflow()外部的网站


因此,我发现了一些有效的方法,即使不是标准行为:

- (void)collapseSecondaryViewController:(UIViewController *)secondaryViewController forSplitViewController:(UISplitViewController *)splitViewController
{
    [self.selectedViewController.navigationController collapseSecondaryViewController:secondaryViewController forSplitViewController:splitViewController];
}
这相当于在
splitViewController:collapseSecondaryViewController:ontopprimaryviewcontroller:
delegate方法中始终返回
YES
。这样,您总是丢弃辅助控制器。
希望这能帮助别人。

它不起作用,同样的问题。你试过了吗?对你有用吗?你好@Zag,对不起,我忘了一个水平计数器。我不知道为什么,但有时(将肖像更改为lands或viceversa后)我们有3个屏幕,而不仅仅是2个,我想这只是为了内部动作的顺序。上面的代码对我有用。嗨@Beto
#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
- (void)collapseSecondaryViewController:(UIViewController *)secondaryViewController forSplitViewController:(UISplitViewController *)splitViewController
{
    [self.selectedViewController.navigationController collapseSecondaryViewController:secondaryViewController forSplitViewController:splitViewController];
}