Fix key commands not working inside split nav controller on iPad

Fixes #179
This commit is contained in:
Shadowfacts 2022-10-10 18:56:27 -04:00
parent 8cf217d2ba
commit dcc8f38f3d
2 changed files with 27 additions and 21 deletions

View File

@ -20,9 +20,6 @@ class MainSplitViewController: UISplitViewController {
private var tabBarViewController: MainTabBarViewController! private var tabBarViewController: MainTabBarViewController!
// private var secondaryNavController: UINavigationController! {
// viewController(for: .secondary) as? UINavigationController
// }
private var secondaryNavController: SplitNavigationController! { private var secondaryNavController: SplitNavigationController! {
viewController(for: .secondary) as? SplitNavigationController viewController(for: .secondary) as? SplitNavigationController
} }
@ -49,8 +46,6 @@ class MainSplitViewController: UISplitViewController {
setViewController(sidebar, for: .primary) setViewController(sidebar, for: .primary)
primaryBackgroundStyle = .sidebar primaryBackgroundStyle = .sidebar
// let secondaryNav = EnhancedNavigationViewController()
// secondaryNav.useBrowserStyleNavigation = true
let splitNav = SplitNavigationController() let splitNav = SplitNavigationController()
setViewController(splitNav, for: .secondary) setViewController(splitNav, for: .secondary)
// don't unnecesarily construct a content VC unless the we're in actually split mode // don't unnecesarily construct a content VC unless the we're in actually split mode

View File

@ -60,6 +60,7 @@ class SplitNavigationController: UIViewController {
self.rootNav.pushViewController(vc, animated: true) self.rootNav.pushViewController(vc, animated: true)
} }
} }
secondaryNav.owner = self
secondaryNav.closeSecondaryImpl = { [unowned self] in secondaryNav.closeSecondaryImpl = { [unowned self] in
self.popToRootViewController(animated: true) self.popToRootViewController(animated: true)
} }
@ -72,26 +73,19 @@ class SplitNavigationController: UIViewController {
// it needs a UINavigationController to be this VC's first child, otherwise it will embed this VC inside // it needs a UINavigationController to be this VC's first child, otherwise it will embed this VC inside
// yet another UINavigationController, which can then cause a crash when we try to embed a nav controller inside // yet another UINavigationController, which can then cause a crash when we try to embed a nav controller inside
// of ourself (because nested nav controllers are forbidden) // of ourself (because nested nav controllers are forbidden)
rootNav.willMove(toParent: self) // and because of that, the view needs to be added here, in between the addChild/didMove(toParent:) calls
addChild(rootNav) // and so the view needs to be loaded immediately
rootNav.didMove(toParent: self) loadViewIfNeeded()
secondaryNav.willMove(toParent: self)
addChild(secondaryNav)
secondaryNav.didMove(toParent: self)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
addChild(rootNav)
rootNav.view.translatesAutoresizingMaskIntoConstraints = false rootNav.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(rootNav.view) view.addSubview(rootNav.view)
rootNav.didMove(toParent: self)
addChild(secondaryNav)
secondaryNav.view.translatesAutoresizingMaskIntoConstraints = false secondaryNav.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(secondaryNav.view) view.addSubview(secondaryNav.view)
secondaryNav.didMove(toParent: self)
separatorView.backgroundColor = .separator separatorView.backgroundColor = .separator
separatorView.translatesAutoresizingMaskIntoConstraints = false separatorView.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(separatorView) view.addSubview(separatorView)
@ -110,10 +104,20 @@ class SplitNavigationController: UIViewController {
secondaryNav.view.bottomAnchor.constraint(equalTo: view.bottomAnchor), secondaryNav.view.bottomAnchor.constraint(equalTo: view.bottomAnchor),
secondaryNav.view.leadingAnchor.constraint(equalTo: separatorView.trailingAnchor), secondaryNav.view.leadingAnchor.constraint(equalTo: separatorView.trailingAnchor),
]) ])
updateSecondaryNavVisibility() updateSecondaryNavVisibility()
} }
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
override func viewDidLoad() {
super.viewDidLoad()
// NOTE: as explained by the large comment above, viewDidLoad is called during initialization, and so things may not be fully setup when it is
}
override func show(_ vc: UIViewController, sender: Any?) { override func show(_ vc: UIViewController, sender: Any?) {
if !canShowSecondaryNav { if !canShowSecondaryNav {
rootNav.pushViewController(vc, animated: true) rootNav.pushViewController(vc, animated: true)
@ -247,6 +251,7 @@ private class SplitRootNavigationController: UINavigationController {
} }
private class SplitSecondaryNavigationController: EnhancedNavigationViewController { private class SplitSecondaryNavigationController: EnhancedNavigationViewController {
fileprivate unowned var owner: SplitNavigationController!
fileprivate var closeSecondaryImpl: (() -> Void)! fileprivate var closeSecondaryImpl: (() -> Void)!
override var viewControllers: [UIViewController] { override var viewControllers: [UIViewController] {
@ -257,6 +262,12 @@ private class SplitSecondaryNavigationController: EnhancedNavigationViewControll
} }
} }
override var next: UIResponder? {
// ordinarily, the next responder in the chain would be the SplitNavigationController's view
// but that would bypass the VC in the root nav, so we reroute the repsonder chain to include it
owner.viewControllers.first!.view
}
private func configureSecondarySplitCloseButton(for viewController: UIViewController) { private func configureSecondarySplitCloseButton(for viewController: UIViewController) {
guard viewController.navigationItem.leftBarButtonItem?.tag != ViewTags.splitNavCloseSecondaryButton else { guard viewController.navigationItem.leftBarButtonItem?.tag != ViewTags.splitNavCloseSecondaryButton else {
return return