Implemented Shim Controller so that we can change out the secondary split view controller when the display mode changes

This commit is contained in:
Maurice Parker 2019-08-01 19:59:56 -05:00
parent 47025e3e16
commit e22088b284
2 changed files with 46 additions and 45 deletions

View File

@ -34,10 +34,11 @@ class AppCoordinator: NSObject, UndoableCommandRunner {
private var masterTimelineViewController: MasterTimelineViewController? private var masterTimelineViewController: MasterTimelineViewController?
private var detailViewController: DetailViewController? { private var detailViewController: DetailViewController? {
if let detailNavController = targetSplitForDetail().viewControllers.last as? UINavigationController { if let subSplit = rootSplitViewController.viewControllers.last?.children.first as? UISplitViewController {
return detailNavController.topViewController as? DetailViewController return subSplit.viewControllers.last as? DetailViewController
} else {
return rootSplitViewController.viewControllers.last?.children.first as? DetailViewController
} }
return nil
} }
private let fetchAndMergeArticlesQueue = CoalescingQueue(name: "Fetch and Merge Articles", interval: 0.5) private let fetchAndMergeArticlesQueue = CoalescingQueue(name: "Fetch and Merge Articles", interval: 0.5)
@ -215,8 +216,10 @@ class AppCoordinator: NSObject, UndoableCommandRunner {
masterNavigationController.pushViewController(masterFeedViewController, animated: false) masterNavigationController.pushViewController(masterFeedViewController, animated: false)
let systemMessageViewController = UIStoryboard.main.instantiateController(ofType: SystemMessageViewController.self) let systemMessageViewController = UIStoryboard.main.instantiateController(ofType: SystemMessageViewController.self)
let controller = addNavControllerIfNecessary(systemMessageViewController, split: rootSplitViewController, showBackButton: true) let detailNavController = addNavControllerIfNecessary(systemMessageViewController, showButton: true)
rootSplitViewController.showDetailViewController(controller, sender: self) let shimController = UIViewController()
shimController.replaceChildAndPinView(detailNavController)
rootSplitViewController.showDetailViewController(shimController, sender: self)
return rootSplitViewController return rootSplitViewController
} }
@ -461,25 +464,15 @@ class AppCoordinator: NSObject, UndoableCommandRunner {
if indexPath == nil { if indexPath == nil {
if !rootSplitViewController.isCollapsed { if !rootSplitViewController.isCollapsed {
let systemMessageViewController = UIStoryboard.main.instantiateController(ofType: SystemMessageViewController.self) let systemMessageViewController = UIStoryboard.main.instantiateController(ofType: SystemMessageViewController.self)
let showBackButton = rootSplitViewController.displayMode != .allVisible installDetailController(systemMessageViewController)
let targetSplit = targetSplitForDetail()
let controller = addNavControllerIfNecessary(systemMessageViewController, split: targetSplit, showBackButton: showBackButton)
targetSplit.showDetailViewController(controller, sender: self)
} }
return return
} }
if detailViewController == nil { if detailViewController == nil {
let targetSplit = targetSplitForDetail()
let detailViewController = UIStoryboard.main.instantiateController(ofType: DetailViewController.self) let detailViewController = UIStoryboard.main.instantiateController(ofType: DetailViewController.self)
detailViewController.coordinator = self detailViewController.coordinator = self
installDetailController(detailViewController)
let showBackButton = rootSplitViewController.displayMode != .allVisible
let controller = addNavControllerIfNecessary(detailViewController, split: targetSplit, showBackButton: showBackButton)
currentArticleIndexPath = indexPath
targetSplit.showDetailViewController(controller, sender: self)
} }
// Automatically hide the overlay // Automatically hide the overlay
@ -846,14 +839,28 @@ private extension AppCoordinator {
// MARK: Double Split // MARK: Double Split
func addNavControllerIfNecessary(_ controller: UIViewController, split: UISplitViewController, showBackButton: Bool) -> UIViewController { func installDetailController(_ detailController: UIViewController) {
if split.isCollapsed { let showButton = rootSplitViewController.displayMode != .allVisible
let controller = addNavControllerIfNecessary(detailController, showButton: showButton)
if isThreePanelMode {
let targetSplit = ensureDoubleSplit()
targetSplit.showDetailViewController(controller, sender: self)
} else {
if let shimController = rootSplitViewController.viewControllers.last {
shimController.replaceChildAndPinView(controller)
}
}
}
func addNavControllerIfNecessary(_ controller: UIViewController, showButton: Bool) -> UIViewController {
if rootSplitViewController.isCollapsed {
return controller return controller
} else { } else {
let navController = UINavigationController(rootViewController: controller) let navController = UINavigationController(rootViewController: controller)
navController.isToolbarHidden = false navController.isToolbarHidden = false
if showBackButton { if showButton {
controller.navigationItem.leftBarButtonItem = split.displayModeButtonItem controller.navigationItem.leftBarButtonItem = rootSplitViewController.displayModeButtonItem
controller.navigationItem.leftItemsSupplementBackButton = true controller.navigationItem.leftItemsSupplementBackButton = true
} }
return navController return navController
@ -861,7 +868,7 @@ private extension AppCoordinator {
} }
func ensureDoubleSplit() -> UISplitViewController { func ensureDoubleSplit() -> UISplitViewController {
if let subSplit = rootSplitViewController.viewControllers.last as? UISplitViewController { if let shimController = rootSplitViewController.viewControllers.last, let subSplit = shimController.children.first as? UISplitViewController {
return subSplit return subSplit
} }
@ -870,7 +877,11 @@ private extension AppCoordinator {
let subSplit = UISplitViewController.template() let subSplit = UISplitViewController.template()
subSplit.preferredDisplayMode = .allVisible subSplit.preferredDisplayMode = .allVisible
subSplit.preferredPrimaryColumnWidthFraction = 0.5 subSplit.preferredPrimaryColumnWidthFraction = 0.5
rootSplitViewController.showDetailViewController(subSplit, sender: self)
let shimController = UIViewController()
shimController.addChildAndPinView(subSplit)
rootSplitViewController.showDetailViewController(shimController, sender: self)
return subSplit return subSplit
} }
@ -883,14 +894,6 @@ private extension AppCoordinator {
} }
} }
func targetSplitForDetail() -> UISplitViewController {
if isThreePanelMode {
return ensureDoubleSplit()
} else {
return rootSplitViewController
}
}
func transitionToThreePanelMode() { func transitionToThreePanelMode() {
defer { defer {
masterNavigationController.viewControllers = [masterFeedViewController] masterNavigationController.viewControllers = [masterFeedViewController]
@ -905,10 +908,9 @@ private extension AppCoordinator {
} else { } else {
let detailController: UIViewController = { let controller: UIViewController = {
if let detailNavController = rootSplitViewController.viewControllers.last as? UINavigationController, if let result = detailViewController {
let detailController = detailNavController.topViewController as? DetailViewController { return result
return detailController
} else { } else {
return UIStoryboard.main.instantiateController(ofType: SystemMessageViewController.self) return UIStoryboard.main.instantiateController(ofType: SystemMessageViewController.self)
} }
@ -919,30 +921,29 @@ private extension AppCoordinator {
let subSplit = ensureDoubleSplit() let subSplit = ensureDoubleSplit()
let masterTimelineNavController = subSplit.viewControllers.first as! UINavigationController let masterTimelineNavController = subSplit.viewControllers.first as! UINavigationController
masterTimelineNavController.viewControllers = [masterTimelineViewController!] masterTimelineNavController.viewControllers = [masterTimelineViewController!]
let detailNavController = addNavControllerIfNecessary(detailController, split: subSplit, showBackButton: false)
subSplit.showDetailViewController(detailNavController, sender: false)
installDetailController(controller)
} }
} }
func transitionFromThreePanelMode() { func transitionFromThreePanelMode() {
rootSplitViewController.preferredPrimaryColumnWidthFraction = UISplitViewController.automaticDimension rootSplitViewController.preferredPrimaryColumnWidthFraction = UISplitViewController.automaticDimension
if let secondarySplit = rootSplitViewController.viewControllers.last as? UISplitViewController { if let shimController = rootSplitViewController.viewControllers.last, let subSplit = shimController.children.first as? UISplitViewController {
if let masterTimelineNav = secondarySplit.viewControllers.first as? UINavigationController, if let masterTimelineNav = subSplit.viewControllers.first as? UINavigationController,
let masterTimeline = masterTimelineNav.topViewController { let masterTimeline = masterTimelineNav.topViewController {
masterNavigationController.pushViewController(masterTimeline, animated: false) masterNavigationController.pushViewController(masterTimeline, animated: false)
} }
if let detailNav = secondarySplit.viewControllers.last as? UINavigationController, let topController = detailNav.topViewController { if let detailNav = subSplit.viewControllers.last as? UINavigationController, let topController = detailNav.topViewController {
let newNav = addNavControllerIfNecessary(topController, split: rootSplitViewController, showBackButton: true) let newNav = addNavControllerIfNecessary(topController, showButton: true)
rootSplitViewController.showDetailViewController(newNav, sender: self) shimController.replaceChildAndPinView(newNav)
} }
} }
} }
} }

@ -1 +1 @@
Subproject commit 277c64868a4a7464f32bbd2b063af3b7736904a3 Subproject commit b8656655f68f207bf9d14e9fda2c928c1bcbe0cf