检测主视图控制器和详细视图控制器何时都在屏幕上?

Posted

技术标签:

【中文标题】检测主视图控制器和详细视图控制器何时都在屏幕上?【英文标题】:Detect when both the master and detail view controller are on screen? 【发布时间】:2014-08-21 21:39:46 【问题描述】:

我在 Xcode 6 中使用 Universal Storyboard 实现了UISplitViewController。现在运行 ios 8 的 iPhone 支持UISplitViewController,默认情况下一次只会在屏幕上显示一个视图控制器。

我需要知道主视图控制器和详细视图控制器何时都在屏幕上 (iPad)。如果两者都在屏幕上,我需要从UITableViewCells 中删除披露指示符 - 仅当屏幕上只有主视图控制器(iPhone)时才渲染它们,就像设置应用程序一样。

我可以简单地检测设备并仅在它是 iPhone 时添加它们,但不建议这样做。新设备可能只显示一个视图控制器而不识别为电话。另一个想法是检测self.splitViewController 是否为nil,但这不起作用,因为它在 iPhone 和 iPad 上都不是 nil,因为它实际上位于 iPhone 上的拆分视图控制器中。

是否可以检测主视图控制器和详细视图控制器何时同时在屏幕上可见?

【问题讨论】:

【参考方案1】:

UISplitViewController

@property(nonatomic, readonly, getter=isCollapsed) BOOL collapsed

当拆分视图控制器内容为 语义上折叠成一个容器。崩溃发生 当拆分视图控制器从水平规则转换时 到一个水平紧凑的环境。倒塌之后, 拆分视图控制器报告只有一个子视图 控制器在其 viewControllers 属性中。另一个视图控制器 被折叠到另一个视图控制器的内容中 委托对象或暂时丢弃。倒塌时, displayMode 属性对拆分视图的外观没有影响 控制器接口。

当拆分视图控制器为 能够同时显示其两个子视图控制器 时间,即使目前没有同时显示它们。在这个 扩展模式,拆分视图控制器对其子项的配置 视图控制器由 displayMode 属性决定。在 此外,viewControllers 属性包含主要和 辅助视图控制器。

在从展开界面过渡到折叠界面期间,值 在折叠过渡完成之前,此属性的值为 NO 并且所有相关的委托方法都已被调用。相似地, 转换回扩展界面时,值为 YES 直到过渡结束。

来自类参考。

感谢 Frederik A. Winkelsdorf:

需要注意的是,.collapsed 也会报告 false,如果 DetailViewController 被缩放以覆盖整个屏幕。如果你真的 想知道两者是否可见,请检查.collapsed 属性旁边 对于splitViewController.displayMode == UISplitViewControllerDisplayMode.AllVisible.,我发现它很有用 处理 iPhone 6 Plus 横向布局。

【讨论】:

在使用 iOS 9 多任务分屏时是否可以在屏幕上重新绘制这些?当您从右侧引入应用程序时,它具有披露指示符。如果您拉伸以占据整个屏幕(不再是多任务处理),则显示指示符仍然存在。如何重新绘制这些单元格以不再拥有它们? 应该注意,如果 DetailViewController 被缩放以覆盖整个屏幕,.collapsed 也会报告 false。如果您真的想知道两者是否可见,请检查 splitViewController.displayMode == UISplitViewControllerDisplayMode.AllVisible 的 .collapsed 属性旁边。我发现它在处理 iPhone 6 Plus 横向布局时很有用。 如何判断是否只有 master 可见? (iPhone)【参考方案2】:

这是检查 UISplitViewController 的 Displaymode 的方法

- (void)splitViewController:(UISplitViewController *)splitViewController willChangeToDisplayMode:(UISplitViewControllerDisplayMode)displayMode 
  if (displayMode == UISplitViewControllerDisplayModePrimaryHidden) 
       NSLog(@"Detail view is visible");
 else if (displayMode == UISplitViewControllerDisplayModeAllVisible) 
       NSLog(@"both are visible");
  

【讨论】:

【参考方案3】:

迅速:

func splitViewController(_ svc: UISplitViewController, willChangeTo displayMode: UISplitViewController.DisplayMode) 

if displayMode == .primaryHidden 
        print("Detail is visible")
    
if displayMode == .allVisible 
        print("Master and Detail are visible")
    

【讨论】:

【参考方案4】:

我发现使用显示模式对我不起作用,但这些对我有用。

func primaryViewController(forExpanding splitViewController: UISplitViewController) -> UIViewController? 
    return nil


func primaryViewController(forCollapsing splitViewController: UISplitViewController) -> UIViewController? 
    return nil

【讨论】:

以上是关于检测主视图控制器和详细视图控制器何时都在屏幕上?的主要内容,如果未能解决你的问题,请参考以下文章

在目标视图控制器 viewWillAppear 中检测向后/弹出导航 [重复]

何时为新屏幕创建新的故事板与视图控制器?

UINavigationController - 检测何时导航回根视图控制器

[iOS]:检测从另一个外部应用程序返回后视图控制器何时出现

知道 -viewWillAppear 何时触发但 -viewWillDisappear 尚未触发

如何检测 UIPageViewController 视图何时更改