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

时间:2015-11-17 02:55:50

标签: ios swift autolayout uisplitviewcontroller

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

if let svc = self.splitViewController {
    svc.preferredDisplayMode = .PrimaryHidden
}

这很有效。当从图表视图导航回详细视图时,我想再次显示拆分视图控制器中的主视图。我把它放在viewWillAppear中。

guard let svc = self.splitViewController else { return }

if svc.preferredDisplayMode != .Automatic {
    svc.preferredDisplayMode = .Automatic
}

这再次完全符合我的预期。问题是详细视图在此过程中更改了大小,从图表视图返回时未正​​确布局。

这是在导航到图表视图之前,以及隐藏UISplitViewController的主视图之前的屏幕截图。 Before

这是从图表视图返回后。 After

我尝试修复此问题的方法是强制详细视图进行布局。我尝试了以下方法:

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()
}

它有点工作,但是当细节视图出现时会在接口中引起一个丑陋的跳跃,然后在一秒钟后重新启动。是否有更好的方法可以在显示之前正确布置视图?

1 个答案:

答案 0 :(得分:3)

我得到了它的工作,并认为我会分享以防任何其他人遇到同样的问题。正如蒂姆在评论中所说,这是一个在链条中尽早运行布局的问题,以便在视图显示在屏幕上之前进行布局。

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

override func viewWillDisappear(animated: Bool) {
    super.viewWillDisappear(animated)
    guard let svc = self.splitViewController else { return }
    svc.preferredDisplayMode = .Automatic
}

这会将拆分视图设置为在过程的早期显示主视图控制器和辅助视图控制器。

我出错的地方是我的详细视图控制器的父级是UINavigationController。我认为,由于这个大小错误,我需要在设置拆分视图控制器以显示主视图和辅助视图后再次将其自行设置。这是一个错误的假设。最终工作的是向UISplitviewController增加一个级别并让它自己执行布局。

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

override func viewWillAppear(animated: Bool) {
    super.viewWillAppear(animated)
    guard let svc = self.splitViewController else { return }
    svc.view.setNeedsLayout()
    svc.view.layoutIfNeeded()
}

这在链条中足够早,所有布局在显示视图之前完成,但是足够晚以至于拆分视图控制器具有适当的大小调整信息以显示主视图和辅助视图。

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