Animate portrait to landscape transitions in three panel mode

This commit is contained in:
Maurice Parker 2019-09-09 16:59:24 -05:00
parent c59584a8f7
commit d80d48916a
3 changed files with 47 additions and 56 deletions

View File

@ -13,6 +13,12 @@ class RootSplitViewController: UISplitViewController {
var coordinator: SceneCoordinator! var coordinator: SceneCoordinator!
override func viewWillTransition(to size: CGSize, with coordinator: UIViewControllerTransitionCoordinator) {
coordinator.animate(alongsideTransition: { [weak self] context in
self?.coordinator.configureThreePanelMode(for: size)
})
}
// MARK: Keyboard Shortcuts // MARK: Keyboard Shortcuts
@objc func scrollOrGoToNextUnread(_ sender: Any?) { @objc func scrollOrGoToNextUnread(_ sender: Any?) {

View File

@ -83,12 +83,6 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
} }
var isThreePanelMode: Bool { var isThreePanelMode: Bool {
return rootSplitViewController.traitCollection.userInterfaceIdiom == .pad &&
!rootSplitViewController.isCollapsed &&
UIDevice.current.orientation.isLandscape
}
var isThreePanelModeConfigured: Bool {
return rootSplitViewController.children.last?.children.first is UISplitViewController return rootSplitViewController.children.last?.children.first is UISplitViewController
} }
@ -274,7 +268,6 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
NotificationCenter.default.addObserver(self, selector: #selector(userDidAddAccount(_:)), name: .UserDidAddAccount, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDidAddAccount(_:)), name: .UserDidAddAccount, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(userDidDeleteAccount(_:)), name: .UserDidDeleteAccount, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDidDeleteAccount(_:)), name: .UserDidDeleteAccount, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(orientationDidChange(_:)), name: UIDevice.orientationDidChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(userDefaultsDidChange(_:)), name: UserDefaults.didChangeNotification, object: nil)
NotificationCenter.default.addObserver(self, selector: #selector(accountDidDownloadArticles(_:)), name: .AccountDidDownloadArticles, object: nil) NotificationCenter.default.addObserver(self, selector: #selector(accountDidDownloadArticles(_:)), name: .AccountDidDownloadArticles, object: nil)
@ -282,7 +275,7 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
let _ = DetailViewControllerWebViewProvider.shared let _ = DetailViewControllerWebViewProvider.shared
} }
func start() -> UIViewController { func start(for size: CGSize) -> UIViewController {
rootSplitViewController = RootSplitViewController() rootSplitViewController = RootSplitViewController()
rootSplitViewController.coordinator = self rootSplitViewController.coordinator = self
rootSplitViewController.preferredDisplayMode = .automatic rootSplitViewController.preferredDisplayMode = .automatic
@ -302,6 +295,8 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
shimController.replaceChildAndPinView(detailNavController) shimController.replaceChildAndPinView(detailNavController)
rootSplitViewController.showDetailViewController(shimController, sender: self) rootSplitViewController.showDetailViewController(shimController, sender: self)
configureThreePanelMode(for: size)
return rootSplitViewController return rootSplitViewController
} }
@ -327,6 +322,21 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
} }
} }
func configureThreePanelMode(for size: CGSize) {
guard rootSplitViewController.traitCollection.userInterfaceIdiom == .pad && !rootSplitViewController.isCollapsed else {
return
}
if size.width > size.height {
if !isThreePanelMode {
transitionToThreePanelMode()
}
} else {
if isThreePanelMode {
transitionFromThreePanelMode()
}
}
}
func selectFirstUnreadInAllUnread() { func selectFirstUnreadInAllUnread() {
selectFeed(IndexPath(row: 1, section: 0)) selectFeed(IndexPath(row: 1, section: 0))
selectFirstUnreadArticleInTimeline() selectFirstUnreadArticleInTimeline()
@ -415,10 +425,6 @@ class SceneCoordinator: NSObject, UndoableCommandRunner, UnreadCountProvider {
} }
} }
@objc func orientationDidChange(_ note: Notification) {
configureThreePanelMode()
}
@objc func userDefaultsDidChange(_ note: Notification) { @objc func userDefaultsDidChange(_ note: Notification) {
self.sortDirection = AppDefaults.timelineSortDirection self.sortDirection = AppDefaults.timelineSortDirection
} }
@ -1589,56 +1595,35 @@ private extension SceneCoordinator {
return shimController return shimController
} }
func configureThreePanelMode() {
guard rootSplitViewController.traitCollection.userInterfaceIdiom == .pad && !rootSplitViewController.isCollapsed else {
return
}
if UIDevice.current.orientation.isLandscape {
if !isThreePanelModeConfigured {
transitionToThreePanelMode()
}
} else {
if isThreePanelModeConfigured {
transitionFromThreePanelMode()
}
}
}
@discardableResult @discardableResult
func transitionToThreePanelMode() -> UIViewController { func transitionToThreePanelMode() -> UIViewController {
defer { defer {
masterNavigationController.viewControllers = [masterFeedViewController] masterNavigationController.viewControllers = [masterFeedViewController]
} }
installTimelineControllerIfNecessary(animated: false)
let controller: UIViewController = {
if let result = detailViewController {
return result
} else {
return UIStoryboard.main.instantiateController(ofType: SystemMessageViewController.self)
}
}()
// Create the new sub split controller (wrapped in the shim of course) and add the timeline in the primary position
let shimController = ensureDoubleSplit()
let subSplit = shimController.children.first as! UISplitViewController
let masterTimelineNavController = subSplit.viewControllers.first as! UINavigationController
masterTimelineNavController.viewControllers = [masterTimelineViewController!]
// Put the detail or no selection controller in the secondary (or detail) position of the sub split
let navController = addNavControllerIfNecessary(controller, showButton: false)
subSplit.showDetailViewController(navController, sender: self)
return shimController
if currentFeedIndexPath == nil && currentArticleIndexPath == nil {
let wrappedSystemMessageController = fullyWrappedSystemMesssageController(showButton: false)
rootSplitViewController.showDetailViewController(wrappedSystemMessageController, sender: self)
return wrappedSystemMessageController
} else {
let controller: UIViewController = {
if let result = detailViewController {
return result
} else {
return UIStoryboard.main.instantiateController(ofType: SystemMessageViewController.self)
}
}()
// Create the new sub split controller (wrapped in the shim of course) and add the timeline in the primary position
let shimController = ensureDoubleSplit()
let subSplit = shimController.children.first as! UISplitViewController
let masterTimelineNavController = subSplit.viewControllers.first as! UINavigationController
masterTimelineNavController.viewControllers = [masterTimelineViewController!]
// Put the detail or no selection controller in the secondary (or detail) position of the sub split
let navController = addNavControllerIfNecessary(controller, showButton: false)
subSplit.showDetailViewController(navController, sender: self)
return shimController
}
} }
func transitionFromThreePanelMode() { func transitionFromThreePanelMode() {

View File

@ -20,7 +20,7 @@ class SceneDelegate: UIResponder, UIWindowSceneDelegate {
window = UIWindow(windowScene: scene as! UIWindowScene) window = UIWindow(windowScene: scene as! UIWindowScene)
window!.tintColor = AppAssets.netNewsWireBlueColor window!.tintColor = AppAssets.netNewsWireBlueColor
window!.rootViewController = coordinator.start() window!.rootViewController = coordinator.start(for: window!.frame.size)
if let shortcutItem = connectionOptions.shortcutItem { if let shortcutItem = connectionOptions.shortcutItem {
window!.makeKeyAndVisible() window!.makeKeyAndVisible()