如何检测当用户切换侧边栏隐藏在分屏视图控制器,以保持次要仅显示模式?



我使用UISplitViewController为我的应用程序创建一个侧边栏-它的风格是.doubleColumn,我离开preferredDisplayMode设置为默认的自动行为。它看起来就像照片应用程序,在横向中,主列和副列都是可见的,而在纵向中,只有副列是可见的(有一个后退按钮来显示主列的顶部)。

在横屏状态下,如果用户轻按侧边栏按钮隐藏主列(或通过键盘快捷键切换),旋转到竖屏状态,然后再旋转回横屏状态,则侧边栏将不被隐藏。这与照片应用不同,在照片应用中,一旦用户隐藏了侧边栏,它就会一直隐藏起来,直到他们取消隐藏(即使在应用启动时也是如此)。我想达到同样的行为。

要做到这一点,我想我可以使用委托函数splitViewController(_willChangeTo:)并检查新的显示模式是否为.secondaryOnly,旧的显示模式是否为.oneBesideSecondary,然后我将在UserDefaults中存储bool,指示用户隐藏了侧边栏,我将preferredDisplayMode设置为.secondaryOnly以保留其隐藏状态之间的旋转。在下次应用启动时,我会检查这是否正确,并将preferredDisplayMode设置为.secondaryOnly。(同样地,当从次要到次要旁边的一个时,将标志和首选显示模式重置为.automatic。)问题是当你旋转设备时委派函数会以相同的状态被调用,这会导致我不恰当地设置标志和首选显示模式。我只需要在用户手动切换侧边栏时这样做,而不是当系统由于可用空间的变化而隐藏它时,例如

如何做到这一点?

我把这个问题带到WWDC的实验室,在那里我得到了一个很好的解决方案!为了保持侧边栏在旋转之间的隐藏状态,您可以实现viewWillTransition(to:with:)来设置一个标志,如systemIsChangingViewSizetrue,调用super,然后将其设置为false。在委托函数.splitViewController(_:willChangeTo:)中检查此标志。当系统启动大小更改时,它将是true;当用户通过切换侧边栏启动大小更改时,它将是false。只有当它是false时,才执行问题中提到的逻辑,以保持用户期望的侧边栏可见性。

private var systemIsChangingViewSize = false
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
systemIsChangingViewSize = true
super.viewWillTransition(to: size, with: coordinator)
systemIsChangingViewSize = false
}
func splitViewController(_ svc: UISplitViewController, willChangeTo displayMode: UISplitViewController.DisplayMode) {
navigationDelegate?.navigationSplitViewController(self, willChangeDisplayMode: displayMode)
if !systemIsChangingViewSize {
if displayMode == .secondaryOnly && svc.displayMode == .oneBesideSecondary {
DispatchQueue.main.async {
svc.preferredDisplayMode = .secondaryOnly
}
} else if displayMode == .oneBesideSecondary && svc.displayMode == .secondaryOnly {
DispatchQueue.main.async {
svc.preferredDisplayMode = .automatic
}
}
}
}

最新更新