【问题标题】:Changing rootViewController for Nav causes UISplitViewController to show detail on Compact portrait orientation更改导航的 rootViewController 会导致 UISplitViewController 显示紧凑纵向方向的详细信息
【发布时间】:2017-07-11 18:04:38
【问题描述】:

我遇到了一个问题,在我将UINavigationController 上的rootViewController 更改为我原来的UINavigationController 后,UISplitViewController 开始在手机设备中显示它的主视图和详细视图紧凑/纵向(不仅适用于大尺寸手机,也适用于其他手机)。

架构的基本概述: TabBarController 包含多个选项卡。这些选项卡之一是UISplitViewController。我目前覆盖以下内容以确保MasterViewController 显示在紧凑的方向上:

func splitViewController(_ splitViewController: UISplitViewController, collapseSecondary secondaryViewController: UIViewController, onto primaryViewController: UIViewController) -> Bool {

    // this prevents phone from going straight to detail on showing the split view controller
    return true
}

这可以正常工作并按预期在纵向上显示母版。在任何时候按下另一个选项卡上的按钮都可以创建一个新的UINavigationController 实例并显示它,其中我正在执行以下操作以将rootViewController 更改为新创建的UINavigationController 以显示:

let appDelegate = UIApplication.shared.delegate
appDelegate?.window??.rootViewController = newNavVC

关闭时,我只是通过上面相同的代码将UINavigationController 换回原来的那个。但是,一旦我这样做了一次(创建导航/显示/关闭),并将我的选项卡切换回带有UISplitViewController 的选项卡,它就会自行更改以显示并排的主详细信息视图。我不知道这在纵向模式下可以实现紧凑的尺寸。我尝试更改为 UISplitViewController 中的 4 种首选显示模式中的任何一种,但这并没有解决问题。

下面是它的样子(iPhone 6 模拟器),我是错过了代表还是误解了崩溃?

之前

之后

【问题讨论】:

    标签: ios swift uinavigationcontroller uisplitviewcontroller


    【解决方案1】:

    您可以使用在此链接中找到的代码 sn-p 替换分配 rootViewController 的逻辑:

    Leaking views when changing rootViewController inside transitionWithView

    基本上,您只需为 UIWindow 类创建一个扩展,它将正确设置根视图控制器。

    extension UIWindow {
    
    /// Fix for https://stackoverflow.com/a/27153956/849645
    func set(rootViewController newRootViewController: UIViewController, withTransition transition: CATransition? = nil) {
    
        let previousViewController = rootViewController
    
        if let transition = transition {
            // Add the transition
            layer.add(transition, forKey: kCATransition)
        }
    
        rootViewController = newRootViewController
    
        // Update status bar appearance using the new view controllers appearance - animate if needed
        if UIView.areAnimationsEnabled {
            UIView.animate(withDuration: CATransaction.animationDuration()) {
                newRootViewController.setNeedsStatusBarAppearanceUpdate()
            }
        } else {
            newRootViewController.setNeedsStatusBarAppearanceUpdate()
        }
    
        /// The presenting view controllers view doesn't get removed from the window as its currently transistioning and presenting a view controller
        if let transitionViewClass = NSClassFromString("UITransitionView") {
            for subview in subviews where subview.isKind(of: transitionViewClass) {
                subview.removeFromSuperview()
            }
        }
        if let previousViewController = previousViewController {
            // Allow the view controller to be deallocated
            previousViewController.dismiss(animated: false) {
                // Remove the root view in case its still showing
                previousViewController.view.removeFromSuperview()
            }
        }
    }
    

    【讨论】:

    • 无需让我们知道您是谁或为什么要发帖。请在此处引用链接中的相关部分,以便于阅读。
    • 感谢您的提示!答案已修改。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2015-02-21
    • 1970-01-01
    • 2014-11-10
    • 2015-03-07
    • 1970-01-01
    • 2016-05-03
    相关资源
    最近更新 更多