问题:似乎没有办法检测 – 在折叠的UISplitViewController中 – 在主服务器(最左侧,主要)视图控制器顶部的详细信息(最右边,辅助)视图控制器被解除时.在详细的View Controller中,viewWillDisappear:和viewDidDisappear:始终为isMovingFromParentViewController和isBeingDismissed报告NO. UISplitViewController viewControllers数组属性不是指示性的.
原因:此问题是相关的,因为如果详细视图控制器在被解除时未被标记为(逻辑上)“空”(即“清除”),则在折叠后续的UISplitViewController扩展时,将重新显示详细的视图控制器(逻辑上)不相关的内容.此外,当展开的UISplitViewController正在折叠时,它无法通过心爱的名称splitViewController选择是仅呈现主视图控制器还是主视图控制器之上的详细视图控制器:collapseSecondaryViewController:ontoPrimaryViewController:delegate方法.
解决方法
我建议将该逻辑移动到主视图控制器,因此它还可以处理除旋转之外的其他情况,例如新结果到达时,或者用户搜索(过滤)结果.
让主视图控制器处理更新详细视图(通过将其详细信息标记为nil,或者最好将其传递给新的详细信息).
您的拆分视图控制器委托将能够确定如何处理辅助视图控制器,并且您的详细视图控制器代码也将更易于维护,因为它不会知道或(紧密)耦合到数据源.
更新:
没有仅限主的UISplitViewController displayMode,其中辅助节点无法显示.显示模式均显示辅助VC,但可以显示,隐藏或覆盖主VC.用户可以旋转设备,或者显示或隐藏主VC(通过presentsWithGesture或displayModeButtonItem),但是对于常规尺寸类,辅助VC将始终显示为空白或不显示.
以下是当设备转换为水平紧凑的大小类时,Apple的Master-Detail模板代码如何确定是否应折叠或丢弃辅助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; } }
请注意,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; }
因为您实例化了一个“空白”细节VC,当用户将SVC从常规大小旋转回到紧凑大小时,SVC代理可以看到没有要显示的细节,因此它会丢弃辅助VC.
这是Apple的方法,它的效果非常好,因为它可以通过旋转,手势或显示模式按钮控制SVC是折叠还是扩展到用户.
我相信你已经在6 Plus上看过Apple的邮件应用程序了.但请注意,一旦用户旋转回常规尺寸类,Apple会做什么.即使用户弹回消息列表,当细节重新出现时仍会显示先前选择的消息.
如果可以使你的应用程序也这样,我鼓励它.它友好,方便,有益,因为它可以节省用户进行(重新)选择的时间,并显示详细信息而不是空白视图.