Swift:如何检测UISplitViewController当前是否显示1个或2个控制器?

10

我该如何检测UISplitViewController当前是只显示1个视图控制器还是在双面板模式下显示了2个视图控制器并且并排显示?

3个回答

13

分割视图控制器会反映在displayMode属性中实际显示的模式:

AllVisible:主要和次要的UIViewControllers并排显示。

PrimaryHidden:隐藏主要的UISplitViewController。

PrimaryOverlay:主要的UISplitViewController覆盖了部分可见的次要视图。

isCollapsed属性为true时,displayMode属性的值被忽略。折叠的分割视图界面只包含一个视图控制器,因此显示模式是不必要的。


总结:要查找屏幕上的详细情况,请使用isCollapsed属性(如果isCollapsed=false) displayMode属性。


2
请注意,这些内容不是在viewDidLoad或viewWillAppear中设置的。如果您需要在加载时执行某些操作,则需要在viewDidAppear中进行检查。 - lostintranslation

4

这里有一个简单的情况:

您正在MasterViewController上并选择了一个单元格。现在,根据UISplitViewController是否折叠,您要么执行一个segue(用红色圈出来),

Segue to perform

将内容传递给DetailViewController(折叠)或更新DetailViewController(未折叠)。

在MasterViewController的“didSelectRowAtIndexPath”方法中,获取对UISplitViewController的引用,并像这样选择要执行的操作:

    override func tableView(tableView: UITableView, didSelectRowAtIndexPath indexPath: NSIndexPath) {
        //Reference to Split View
        guard let splitView = self.splitViewController else {
            return
        }
        //Check the collapsed property
        if splitView.collapsed {
            self.performSegueWithIdentifier("segueToDetail", sender: self)
        }else {
            //Get reference to your details navigation controller
            guard let detailViewNavigationController  = self.splitViewController?.viewControllers[1] as? UINavigationController else {
                return
            }
            //Get a reference to your custom detail view controller
            guard let detailController = detailViewNavigationController.viewControllers[0] as? MyCustomViewController else {
                return
            }
            //Call your custom function to update the detail view controller
            detailController.updateSomething()
        }
     }

如果您不想使用UISplitViewController的"collapsed"属性,可以像这样检查视图控制器属性的数量。
        if splitView.viewControllers.count == 1 {
            self.performSegueWithIdentifier("segueToDetail", sender: self)
        }else splitView.viewControllers.count == 2 {
            guard let detailViewNavigationController  = self.splitViewController?.viewControllers[1] as? UINavigationController else {
                return
            }

            guard let detailController = detailViewNavigationController.viewControllers[0] as? MyCustomViewController else {
                return
            }

            detailController.updateSomething()
        }

另一种选择是从主视图控制器设置委托到详细视图控制器。如果您不想像此示例那样到达视图控制器链,则此方法将很有效。这里有一个关于此方法的教程。请注意“连接主控制器和详细信息”部分。
只需要注意:我测试了UISplitViewControllers“displayMode”属性的切换。该属性未给我足够的信息来解决问题。原因是当您处于水平紧凑模式和水平扩展模式时,该属性设置为.AllVisible。

最后,在我离开之前。我喜欢这样做的方式,因为很多时候你知道你将需要一个UISplitViewController,所以你从模板创建一个项目。您会注意到模板已经设置了segue。这个模板非常适合手机,但对于iPad和iPhone6+来说并不足够。如果在项目创建后将UISplitViewController拖放到story board上,您会注意到详细视图既没有嵌入UINavigationController,也没有从主视图到详细视图的segue。我想这只是更多需要设置的东西!


0

UISplitViewController有一个名为“collapsed”的属性。


在 iPhone 上(仅显示一个屏幕),collapsed 为 false。 - Daniele B
4
在 iPhone 初次启动时,“collapsed” 总是为 false,然后在一段时间后它才会折叠。 - Jason Nam
有点头疼 :( - Jason Nam
我也看到了@JasonNam提到的问题,即在启动时collapsed始终为false,然后在一段时间后折叠。为了解决这个问题,我检查了traitCollection.horizontalSizeClass以查看它是否为.unspecified。如果是,则collapsed不可靠。 - Cody

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接