折叠主/细节UISplitViewController:检测细节查看控制器解雇?

Gar*_*ary 9 uisplitviewcontroller ios8

情况:iPhone 6 Plus,UISplitViewController水平旋转紧凑(折叠)和水平常规(扩展)尺寸类.

问题:似乎无法检测 - 在折叠状态下UISplitViewController- 在主控(最左侧,主要)视图控制器顶部的详细信息(最右侧,辅助)视图控制器被解除时.在详细视图控制器,既viewWillDisappear:viewDidDisappear:始终报告NOisMovingFromParentViewControllerisBeingDismissed.UISplitViewController viewControllers数组属性不是指示性的.

原因:此问题是相关的,因为如果详细视图控制器在被解除时未被标记为(逻辑上)"空"(即"清除"),则在UISplitViewController折叠后续扩展时,将重新显示详细视图控制器(逻辑上)不相关的内容.此外,当展开的UISplitViewController是折叠时,它无法通过心爱的命名splitViewController:collapseSecondaryViewController:ontoPrimaryViewController:委托方法选择是仅呈现主视图控制器还是在主视图控制器之上呈现详细视图控制器.

小智 0

看来您正在尝试让详细视图控制器处理将自身标记为“空”。

我建议将该逻辑移至主视图控制器,这样它还可以处理除旋转之外的其他情况,例如当新结果到达或用户搜索(过滤)结果时。

让主视图控制器处理更新详细信息视图(通过将其详细信息标记为 nil,或者最好向其传递新详细信息)。

您的分割视图控制器委托将能够确定如何处理辅助视图控制器,并且您的详细视图控制器代码也将更易于维护,因为它不会了解数据源,也不会(紧密)耦合到数据源。

更新:

不存在UISplitViewController displayMode无法显示辅助设备的仅主设备。显示模式均显示辅助 VC,但可能显示、隐藏或覆盖主 VC。用户可以旋转设备,或者显示或隐藏主 VC(通过presentsWithGesturedisplayModeButtonItem),但对于常规尺寸类别,辅助 VC 将始终显示,无论是否为空白。

以下是当设备转换到水平紧凑尺寸类别时,Apple 的主从模板代码如何确定是否应折叠或丢弃辅助 VC。

- (BOOL)splitViewController:(UISplitViewController *)splitViewController collapseSecondaryViewController:(UIViewController *)secondaryViewController ontoPrimaryViewController:(UIViewController *)primaryViewController {
    if ([secondaryViewController isKindOfClass:[UINavigationController class]] && [[(UINavigationController *)secondaryViewController topViewController] isKindOfClass:[YHWHDetailViewController class]] && ([(YHWHDetailViewController *)[(UINavigationController *)secondaryViewController topViewController] detailItem] == nil)) {
        // Return YES to indicate that we have handled the collapse by doing nothing; the secondary controller will be discarded.
        return YES;
    } else {
        return NO;
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意,Apple 使用详细视图控制器上的属性作为标志。

我理解您认为是否应折叠或丢弃辅助 VC 的决定应基于用户是否明确地忽略辅助 VC(同时以水平紧凑尺寸折叠)。

我知道您试图在细节 VC 消失时使其自身“清晰”,但假设它已被解雇(丢弃)并且您没有对它进行强引用,那么这将是一个非操作。

如果细节不存在(或使dataSource细节无效),那就更简单了。

如果您坚持不懈,并且无法清除详细信息,那么您必须:

  • 保留某种类型的标志(无论是 BOOL 还是 nil 对象)来反映细节的内容是否已变得“无关紧要”,并依靠该标志来确定将来辅助视图控制器是否应该(再次)折叠。
  • 检查详细信息(在再次折叠之前),看看dataSource其内容是“相关”还是“不相关”。

如果您使用详细的 VC 属性作为标志,则有以下好处。当 SVC 折叠并且详细 VC 已被“明确驳回”时,不再有辅助 VC 可以从主 VC 中分离出来。

- (UIViewController *)splitViewController:(UISplitViewController *)splitViewController
separateSecondaryViewControllerFromPrimaryViewController:(UIViewController *)primaryViewController{

    if ([primaryViewController isKindOfClass:[UINavigationController class]]) {
        for (UIViewController *controller in [(UINavigationController *)primaryViewController viewControllers]) {
            if ([controller isKindOfClass:[UINavigationController class]] && [[(UINavigationController *)controller visibleViewController] isKindOfClass:[DetailViewController class]]) {
                return controller;
            }
        }
    }

    // No detail view present
    UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"Main" bundle:nil];
    UINavigationController *secondaryViewController = [storyboard instantiateViewControllerWithIdentifier:@"SecondaryViewController"];

    // Ensure back button is enabled
    UIViewController *detailViewController = [secondaryViewController visibleViewController];
    detailViewController.navigationItem.leftBarButtonItem = self.splitViewController.displayModeButtonItem;
    detailViewController.navigationItem.leftItemsSupplementBackButton = YES;

    return secondaryViewController;

}
Run Code Online (Sandbox Code Playgroud)

因为您实例化了“空白”详细信息 VC,所以当用户将 SVC 从常规大小旋转回紧凑大小时,SVC 委托可以看到没有可显示的详细信息,因此它会丢弃辅助 VC。

这就是 Apple 的方法,而且效果非常好,因为它将 SVC 是折叠还是展开的控制权留给了用户,通过旋转、手势或显示模式按钮。

我相信您在 6 Plus 上见过 Apple 的邮件应用程序。但请注意,一旦用户恢复到常规尺寸级别,苹果会做什么。即使用户弹回消息列表,当详细信息重新出现时,仍会显示先前选择的消息。

如果可以让您的应用程序也这样做,我会鼓励它。它友好、方便且有益,因为它节省了用户进行(重新)选择的时间,并且显示详细信息而不是空白视图。