Ios 显示/隐藏UISplitViewController的主视图控制器移动详细视图

Ios 显示/隐藏UISplitViewController的主视图控制器移动详细视图,ios,swift,autolayout,uisplitviewcontroller,Ios,Swift,Autolayout,Uisplitviewcontroller,我有一个UISplitViewController,用于在iPad上实现主/细节功能。主视图控制器显示项目列表,当用户选择一个项目时,详细信息将显示在详细视图控制器中。我已将详细视图控制器设置为导航到另一个视图控制器以显示图形。发生这种情况时,我会在prepareForSeque中使用以下行隐藏主视图控制器 if let svc = self.splitViewController { svc.preferredDisplayMode = .PrimaryHidden } 这很有效。当

我有一个UISplitViewController,用于在iPad上实现主/细节功能。主视图控制器显示项目列表,当用户选择一个项目时,详细信息将显示在详细视图控制器中。我已将详细视图控制器设置为导航到另一个视图控制器以显示图形。发生这种情况时,我会在prepareForSeque中使用以下行隐藏主视图控制器

if let svc = self.splitViewController {
    svc.preferredDisplayMode = .PrimaryHidden
}
这很有效。当从图形视图导航回详图视图时,我想再次从拆分视图控制器显示主视图。我把这个放在视图中,它就会出现

guard let svc = self.splitViewController else { return }

if svc.preferredDisplayMode != .Automatic {
    svc.preferredDisplayMode = .Automatic
}
同样,这也完全符合我的预期。问题在于详图视图在此过程中会更改大小,并且从图形视图返回时布局不正确

以下是导航到图形视图之前以及隐藏UISplitViewController主视图之前的屏幕截图。

这是在从图表视图返回之后。

我试图解决这个问题,是为了强制细节视图自行布局。我尝试了以下方法:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    guard let svc = self.splitViewController else { return }
    let detailNavController = svc.viewControllers[svc.viewControllers.count-1] as! UINavigationController
    detailNavController.view.setNeedsLayout()
}
override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    guard let svc = self.splitViewController else { return }
    svc.view.setNeedsLayout()
    svc.view.layoutIfNeeded()
}

它在某种程度上可以工作,但在细节视图出现时会在界面中引起一个丑陋的跳跃,然后在第二次之后重新显示。是否有更好的方法在视图显示之前将其正确布局?

我让它工作起来了,我想如果其他人遇到同样的问题,我会与大家分享。正如Tim在评论中所说的,这是一个在链中尽早运行布局的问题,以便在视图显示在屏幕上之前安排好内容

我在图形视图控制器场景中执行了以下操作:

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    guard let svc = self.splitViewController else { return }
    svc.preferredDisplayMode = .Automatic
}
这会将拆分视图设置回在过程的早期同时显示主视图控制器和次视图控制器

我出错的地方是详图视图控制器的父级是UINavigationController。我假设由于大小不对,所以在设置分割视图控制器以显示主视图和次视图后,我需要使其重新布局。这是一个错误的假设。最终起作用的是将UISplitviewController再提升一个级别,让它自己执行布局

在我的详细视图控制器中,我执行了以下操作:

override func viewWillLayoutSubviews() {
    super.viewWillLayoutSubviews()

    guard let svc = self.splitViewController else { return }
    let detailNavController = svc.viewControllers[svc.viewControllers.count-1] as! UINavigationController
    detailNavController.view.setNeedsLayout()
}
override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    guard let svc = self.splitViewController else { return }
    svc.view.setNeedsLayout()
    svc.view.layoutIfNeeded()
}
这在链中足够早,以至于在显示视图之前完成所有布局,但足够晚,以至于拆分视图控制器具有适当的大小调整信息来显示主视图和次视图


希望这对其他人有所帮助,并感谢您的评论。

如果它正在工作但正在跳跃,您需要将
setNeedsLayout
放在链的前面。尝试将
super.viewWillLayoutSubviews()
放在覆盖块的末尾。不幸的是,这似乎没有改变任何事情。谢谢你的建议。你是在用自动布局的故事板吗?非常感谢。帮了很多汉克斯,这帮了我。尤其是
svc.view
布局强制。隐藏主控制器时,我的平板电脑上有一个奇怪的空白区域。