iOS8 UISplitViewController 的显示模式按钮行为

iOS8 UISplitViewController's display mode button behavior

当我在 UISplitViewController 中有多个详细视图时,我在 iOS8 中遇到问题,问题只出现在 水平紧凑模式 .

我的情节提要类似于:

如您所见,我的主人 table 有两种类型的单元格,每一种都使用 显示详细信息 连接到详细信息视图的 "its own" 层次结构继续。因此,单击第一个单元格将在拆分视图的次要区域加载 D1(及其根),单击第二个单元格将在那里加载 D2。

我在准备 segue 时将拆分视图的超级智能显示模式按钮添加到任何详细信息的导航项中:

controller.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
controller.navigationItem.leftItemsSupplementBackButton = YES;

除一种情况外一切正常:

现在一旦我这样做了,我的魔术显示模式按钮就会显示“完全不是我想要的行为。当我在 内部导航 D1 或 D2 本身时,这种 'history' 返回是可取的(我相信这个按钮足够聪明,可以做到这一点)。但是当我在顶层的时候,我想让它打开初级区域。基本上我需要更多类似左抽屉开启器的东西(比如 Android)。

基本原理: 我的 D1 正在表达某种 error/incomplete 状态(无连接/无用户等),当状态为 'fixed' 时'normal' UI 通过 D2 或 D3 或任何其他方式加载。此时看到错误页面的后退按钮真的很奇怪。当我从 D2 转到 D3 时,这个历史功能甚至很好,所以如果有办法以某种方式从历史中删除 D1 - 这也会帮助我。

在最坏的情况下,我会自己完成按钮逻辑 - 我需要一种方法来打开抽屉(主要区域),该信息也会对我有所帮助。

所以,经过一段时间的努力,我找到了一种方法来获得我需要的东西。事实证明,在折叠模式下,拆分视图 "becomes" 只是一个简单的导航控制器。所以在 D2 之上有一个父导航控制器(它也是一个导航控制器)。下面在 D2 的 根控制器的 viewDidLoad 中编写的代码可以解决问题:

UINavigationController* parentNavi = self.navigationController.navigationController;
if (parentNavi != nil) {
    // will get here only in collapsed mode
    NSMutableArray *controllers = [NSMutableArray arrayWithArray:parentNavi.viewControllers];
    NSMutableIndexSet *set = [NSMutableIndexSet indexSet];
    for (UIViewController *controller in controllers) {
        if ([controller.title isEqualToString:@"D1"]) {
            [set addIndex:[controllers indexOfObject:controller]];
        }
    }
    [controllers removeObjectsAtIndexes:set];
    parentNavi.viewControllers = controllers;
}

只有在紧凑尺寸时,代码才会进入if语句。清理控制器后,显示模式按钮指向主要区域。此代码也非常灵活 - 您可以删除堆栈中不需要的任何页面。