我有一个 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 模式下不会被调用)。
我的第一个问题是我正在做的事情是否可以,或者是否存在一些固有的问题,表现为“黑暗模式”问题。
任何见解或指示将不胜感激!
我已向 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]
}