当我 collapse/expand 屏幕时,displayModeButtonItem 正在消失

displayModeButtonItem is disappearing when I collapse/expand screen

所以我的用例是在详细视图中有一个 TabBarController,大约四个选项卡,每个选项卡都有自己的 NavigationController。都是通过故事板。然后在我的 App Delegate 上我有这个:

let splitViewController = self.window!.rootViewController as! UISplitViewController
splitViewController.preferredDisplayMode = .allVisible
let tabBarController = splitViewController.viewControllers[splitViewController.viewControllers.count-1] as! UITabBarController
for item in tabBarController.viewControllers!{
        let navigationController = item as! UINavigationController
        navigationController.topViewController!.navigationItem.leftBarButtonItem = splitViewController.displayModeButtonItem
}

所以我在每个 NavigationController 上都有一个 Button。问题首先是当我使用第一个选项卡上的按钮时,它工作正常,但是一旦我移动选项卡,当我 return 到前一个选项卡并使用按钮时,它就会消失。然后,当我切换到另一个选项卡时,它会返回。令人惊讶的是,这不会发生在最后一个选项卡上。我试图寻找解决方案,但找不到任何解决方案。所以我现在处于低迷状态。

我添加了一个 gif 来展示这个行为。

编辑:我不知道这是否重要,但这个项目仅限景观。

我认为这是一个 UIKit 错误。行为实际上取决于您设置 navigationItem.leftBarButtonItem 的视图控制器的顺序。该错误将在加载最后一个视图后开始重现。

虽然有一个 hacky 解决方法。将此添加到对象,该对象实现了 UISplitViewController

UISplitViewControllerDelegate
func splitViewController(_ svc: UISplitViewController, willChangeTo displayMode: UISplitViewControllerDisplayMode) {
    DispatchQueue.main.async {
        let tabBarController = svc.viewControllers.last as! UITabBarController
        let navigationController = tabBarController.selectedViewController as! UINavigationController
        navigationController.viewControllers.first?.navigationItem.leftBarButtonItem = nil
        navigationController.viewControllers.first?.navigationItem.leftBarButtonItem = svc.displayModeButtonItem
    }
}

它可以在没有 DispatchQueue.main.async 的情况下工作,但是 leftBarButtonItem 的位置由于某种原因会出错,而且我不知道如何更新它的布局。

希望对您有所帮助。

我会根据 Apple 的官方支持添加一个答案作为附加信息,以防有人疑惑:

"UISplitViewController 的displayModeButtonItem 一次只能驻留在视图层级中的一个地方,不能驻留在多个地方或多个视图控制器。当前你将它指向tabbar 中的所有视图控制器。 正如我们所见,这样做会产生不可预测的结果。"

已接受的答案虽然是一个相当棘手的解决方法,但却有效。不过,Apple 的支持建议是在 TabBarController 级别对其进行处理。