当overrideUserInterfaceStyle设置为.dark时,UISplitViewController的detailViewController为nil

问题描述 投票:0回答:1

我有一个 UISplitViewController,其中有两个 UINavigationController 作为主视图控制器和详细视图控制器,是使用 Storyboard 创建的。主控制器有一个静态 UITableViewController,单击一行将设置详细视图以在详细视图导航控制器中加载。

一切都按预期工作,除了当我将 overrideUserInterfaceStyle 设置为“黑暗模式”时。完成后,UISplitViewController 的 viewControllers 数组中只有 1 个元素 - 主视图控制器。

我尝试使用简化的示例重新创建问题,并成功重现该问题。

可重现的测试用例位于 https://github.com/sridharrajagopal/TestApp

protocol RootSettingsViewControllerSelectionDelegate : AnyObject {
    func viewControllerSelected(_ vc: String)
}

class RootSettingsViewController: UITableViewController, MFMailComposeViewControllerDelegate {
    
    weak var delegate: RootSettingsViewControllerSelectionDelegate?
    
    override func viewDidLoad() {
        super.viewDidLoad()

        if (UIDevice.current.userInterfaceIdiom == .pad) {
            let indexPath = IndexPath(row: 0, section: 0)
            tableView.selectRow(at: indexPath, animated: true, scrollPosition: UITableView.ScrollPosition.top)
            tableView.delegate?.tableView!(tableView, didSelectRowAt: indexPath)
        }
    }
    
    
    
    override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
        if (indexPath.section == 2 && indexPath.row == 2)  {
            // emailUs()
        } else if (indexPath.section == 0 && indexPath.row == 0) {
            delegate?.viewControllerSelected("A")
        } else if (indexPath.section == 0 && indexPath.row == 1) {
            delegate?.viewControllerSelected("B")
        } else if (indexPath.section == 0 && indexPath.row == 2) {
            delegate?.viewControllerSelected("C")
        } 
        if let detailViewController = delegate as? SettingsSecondaryNavigationViewController {
            splitViewController?.showDetailViewController(detailViewController, sender: nil)
        }
    }
    
}

class SettingsSecondaryNavigationViewController: UINavigationController {

    override init(nibName nibNameOrNil: String?, bundle nibBundleOrNil: Bundle?) {
        super.init(nibName: nibNameOrNil, bundle: nibBundleOrNil)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
    }
    
}

extension SettingsSecondaryNavigationViewController: RootSettingsViewControllerSelectionDelegate {
    func viewControllerSelected(_ vc: String) {
        if (vc == "A") {
            let detailViewController = UIViewController()
            detailViewController.view.backgroundColor = .red
            self.viewControllers = [detailViewController]
        } else if (vc == "B") {
            let detailViewController = UIViewController()
            detailViewController.view.backgroundColor = .green
            self.viewControllers = [detailViewController]
            
        } else if (vc == "C") {
            let detailViewController = UIViewController()
            detailViewController.view.backgroundColor = .blue
            self.viewControllers = [detailViewController]
            
        } else if (vc == "D") {
            let detailViewController = UIViewController()
            detailViewController.view.backgroundColor = .purple
            self.viewControllers = [detailViewController]
            
        }
        
    }

}

class SettingsSplitViewController: UISplitViewController, UISplitViewControllerDelegate {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        delegate = self
        
        let detailViewController =
          (self.viewControllers.last as? SettingsSecondaryNavigationViewController)
        
        let primaryViewController =
          (self.viewControllers.first as? UINavigationController)?
            .topViewController as? RootSettingsViewController
        
        // This is where it bombs, as detailViewController is nil 
        primaryViewController!.delegate = detailViewController!

        preferredDisplayMode = UISplitViewController.DisplayMode.oneBesideSecondary
    }
    
    func splitViewController(
        _ splitViewController: UISplitViewController,
        collapseSecondary secondaryViewController: UIViewController,
        onto primaryViewController: UIViewController
    ) -> Bool {
        
        return true
    }
}

此时我很困惑。如果 overrideUserInterfaceStyle 为 .light 或 .unspecified(匹配系统设置),则一切正常。

我看到加载应用程序时,当 overrideUserInterfaceStyle 为 .light 或 .unspecified 时,SettingsSecondaryNavigationViewController 的 viewDidLoad 会被调用(甚至在加载实际的 UISplitViewController 之前,但在 .dark 模式下不会被调用)。

我的第一个问题是我正在做的事情是否可以,或者是否存在一些固有的问题,表现为“黑暗模式”问题。

任何见解或指示将不胜感激!

ios swift storyboard uisplitviewcontroller darkmode
1个回答
0
投票

我已向 Apple 提交了错误报告。

我通过使用故事板 ID 在 UISplitViewController 的 viewDidLoad 中以编程方式创建主视图控制器和详细视图控制器来解决这个问题,以从 Interface Builder 故事板加载 viewController。

override func viewDidLoad() {
    super.viewDidLoad()
    
    loadViewControllers()
    
    delegate = self

    preferredDisplayMode = UISplitViewController.DisplayMode.oneBesideSecondary
}

private func loadViewControllers() {
    
    let storyboard = UIStoryboard(name: "Main", bundle: nil)
    
    let primaryViewController = storyboard.instantiateViewController(withIdentifier: "RootSettingsViewController") as! RootSettingsViewController
    
    let detailViewController = storyboard.instantiateViewController(withIdentifier: "SettingsSecondaryNavigationViewController") as! SettingsSecondaryNavigationViewController
            
    primaryViewController.delegate = detailViewController
    
    let navController = UINavigationController(rootViewController: primaryViewController)
    
    self.viewControllers = [navController, detailViewController]
}
© www.soinside.com 2019 - 2024. All rights reserved.