问题描述
我正在实现iOS 14(iPadOS 14)侧边栏(带有TripleColumn的UISplitViewController),并且具有奇怪的“侧边栏切换图标”行为。 在iOS 13中,我使用带有一些拆分视图和表格视图的选项卡栏,因此我需要三列而不是双列来工作。
例如,使用“航班”标签中的侧栏需要三列:
有些选项卡只有一列(在iOS 13中,它是一个表视图而不是拆分视图)。我将补充视图设置为nil,并通过调用iOS 14中实现的“ hide”方法隐藏视图(请参见下面的代码):
将自动显示左上方的“侧栏切换图标”。单击切换图标后,边栏正确隐藏,但是在我的辅助视图(嵌入在UINavigationController中的UITableViewController)上创建了一个“后退按钮”:
按下(单击)后退按钮没有响应。用户仍然可以从屏幕的左边缘滑动以重新显示边栏,但“后退按钮”令人困惑。我的预期行为是,在侧边栏中选择了切换图标之后,在辅助视图中显示了“侧边栏切换图标”而不是“后退按钮”。然后,在辅助视图中按下“侧栏切换图标”后,侧栏会重新出现。
类似于iOS 14(iPadOS 14)中的“照片”应用程序,显示了切换按钮,而不是后退按钮。然后单击切换图标将再次显示侧边栏。 (但这是一个双列拆分视图)
我的代码:
SceneDelegate.swift:
func scene(_ scene: UIScene,willConnectTo session: UIScenesession,options connectionoptions: UIScene.Connectionoptions) {
if let windowScene = scene as? UIWindowScene {
let window = UIWindow(windowScene: windowScene)
if #available(iOS 14.0,*) {
let main = UIStoryboard(name: "Main",bundle: nil)
let splitViewController = UISplitViewController(style: .tripleColumn)
splitViewController.preferreddisplayMode = .twoBesideSecondary
splitViewController.preferredSplitBehavior = .tile
splitViewController.setViewController(SideBarViewController(),for: .primary)
// fall back for compact screen
splitViewController.setViewController(main.instantiateInitialViewController(),for: .compact)
window.rootViewController = splitViewController
self.window = window
window.makeKeyAndVisible()
}
}
}
SideBarViewController:
// if the first tab (dashboard) was selected
private func selectDashboardTab() {
if #available(iOS 14.0,*) {
let dashboardVC = UIStoryboard(name: "Main",bundle: nil).instantiateViewController(withIdentifier: "DashboardTab") as? UINavigationController
splitViewController?.preferredPrimaryColumnWidth = 250.0
splitViewController?.preferreddisplayMode = .twoBesideSecondary
splitViewController?.preferredSplitBehavior = .tile
splitViewController?.setViewController(dashboardVC,for: .secondary)
splitViewController?.setViewController(nil,for: .supplementary)
splitViewController?.hide(.supplementary)
}
}
解决方法
讨论到后期,但...我遇到过类似的行为。
就在设置你的次要之前,将它设置为 nil。奇怪,我知道,但它为我修好了。像这样:
splitViewController?.setViewController(nil,for: .secondary)
splitViewController?.setViewController(dashboardVC,for: .secondary)
,
我能够重现该问题...但无法使用可用的 API 来规避它。 Apple 顽固地决定,在 3 列布局中,侧边栏图标将始终位于辅助控制器中。
话虽如此,我已经编写了一个 hack 来修复它。我设法创建了一个 UISplitViewController 子类,它“伪造”了一个可编辑的 style
属性,从而允许我们设置列数(hack 只是创建了一个全新的控制器并使其成为新的 rootViewController)。
hack 让我们可以随意切换 2 列和 3 列布局,似乎解决了侧边栏图标问题。
链接到下面的 Xcode 项目。但这是它的要点:
class AdaptableSplitViewController: UISplitViewController {
override var style: Style {
get {
super.style
}
set {
guard newValue != style else { return }
let primaryController = viewController(for: .primary)
let supplementaryController = viewController(for: .supplementary)
let secondaryController = viewController(for: .secondary)
let newSplitController = AdaptableSplitViewController(style: newValue)
newSplitController.setViewController(primaryController,for: .primary)
newSplitController.setViewController(secondaryController,for: .secondary)
if newValue == .tripleColumn {
newSplitController.setViewController(supplementaryController,for: .supplementary)
}
UIApplication.shared.windows[0].rootViewController = newSplitController
}
}
}
如果这有帮助,请告诉我。