Skip to content

Instantly share code, notes, and snippets.

@rchatham
Last active February 26, 2017 04:01
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rchatham/07efd6fb19c48dc2b1596f1b3b71f559 to your computer and use it in GitHub Desktop.
Save rchatham/07efd6fb19c48dc2b1596f1b3b71f559 to your computer and use it in GitHub Desktop.
CoordinatorType
//
// CoordinatorType.swift
//
// Created by Reid Chatham on 9/19/16.
//
#if os(macOS)
import Cocoa
public typealias MyViewController = NSViewController
public typealias MyTabController = NSTabViewController
#elseif os(iOS)
import UIKit
public typealias MyViewController = UIViewController
public typealias MyTabController = UITabBarController
#endif
// MARK: - CoordinatorType
public protocol CoordinatorType: CoordinatorTypeDelegate {
weak var delegate: CoordinatorTypeDelegate? { get }
var childCoordinators: [CoordinatorType] { get set }
func viewController() -> MyViewController
func start(onViewController viewController: MyViewController, animated: Bool)
func start(onViewController viewController: MyViewController, animated: Bool, withUrl: URL?)
func start(onViewController viewController: MyViewController, animated: Bool, withPath: String?)
}
extension CoordinatorType {
public func start(onViewController viewController: MyViewController, animated: Bool) {
viewController.presents(self.viewController(), animated: animated, completion: nil)
}
public func start(onViewController viewController: MyViewController, animated: Bool, withUrl: URL?) {
start(onViewController: viewController, animated: animated)
}
public func start(onViewController viewController: MyViewController, animated: Bool, withPath: String?) {
start(onViewController: viewController, animated: animated)
}
}
extension MyViewController {
fileprivate func presents(_ viewController: MyViewController, animated: Bool, completion: (()->Void)? = nil) {
#if os(iOS)
(self as UIViewController).present((viewController as UIViewController), animated: animated, completion: completion)
#elseif os(macOS)
(self as NSViewController).presentViewControllerAsSheet(viewController as NSViewController)
#endif
}
}
// MARK: - CoordinatorTypeDelegate
public protocol CoordinatorTypeDelegate: class {
func coordinatorDidFinish(_ coordinator: CoordinatorType)
}
extension CoordinatorTypeDelegate where Self: CoordinatorType {
public func coordinatorDidFinish(_ coordinator: CoordinatorType) {
guard let idx = childCoordinators.index(where: { $0 === coordinator }) else { return }
childCoordinators.remove(at: idx)
}
}
#if os(iOS)
// MARK: - NavigationCoordinator
public protocol NavigationCoordinatorType: CoordinatorType {
weak var navigationController: UINavigationController? { get set }
func rootViewController() -> UIViewController
}
extension NavigationCoordinatorType {
public func navigationController() -> UINavigationController {
return viewController() as! UINavigationController
}
public func viewController() -> UIViewController {
let nav = UINavigationController()
start(onNavigationController: nav, animated: false)
return nav
}
public func start(onViewController viewController: UIViewController, animated: Bool) {
if let nav = viewController as? UINavigationController {
start(onNavigationController: nav, animated: animated)
} else {
let nav = UINavigationController()
start(onNavigationController: nav, animated: false)
viewController.presents(nav, animated: animated, completion: nil)
}
}
private func start(onNavigationController navigationController: UINavigationController, animated: Bool) {
let root = rootViewController()
navigationController.pushViewController(root, animated: animated)
self.navigationController = navigationController
}
}
#endif
// MARK: - TabCoordinator
public protocol TabCoordinatorType: CoordinatorType {
weak var tabController: MyTabController? { get set }
func rootViewControllers() -> [MyViewController]
}
extension TabCoordinatorType {
public func tabController() -> MyTabController {
return viewController() as! MyTabController
}
public func viewController() -> MyViewController {
let tab = MyTabController()
start(onTabController: tab, animated: false)
return tab
}
public func start(onViewController viewController: MyViewController, animated: Bool) {
if let tab = viewController as? MyTabController {
start(onTabController: tab, animated: animated)
} else {
let tab = MyTabController()
start(onTabController: tab, animated: false)
viewController.presents(tab, animated: true, completion: nil)
}
}
private func start(onTabController tabController: MyTabController, animated: Bool) {
let roots = rootViewControllers()
tabController.setTabViewControllers(roots, animated: animated)
self.tabController = tabController
}
}
extension MyTabController {
fileprivate func setTabViewControllers(_ viewControllers: [MyViewController], animated: Bool) {
#if os(iOS)
(self as UITabBarController).setViewControllers(viewControllers, animated: animated)
#elseif os(macOS)
(self as NSTabViewController).childViewControllers = viewControllers
#endif
}
}
//
// CoordinatorType.swift
//
// Created by Reid Chatham on 9/19/16.
//
import UIKit
// MARK: - CoordinatorType
public protocol CoordinatorType: CoordinatorTypeDelegate {
weak var delegate: CoordinatorTypeDelegate? { get }
var childCoordinators: [CoordinatorType] { get set }
func viewController() -> UIViewController
func start(onViewController viewController: UIViewController)
func start(onViewController viewController: UIViewController, animated: Bool)
func start(onViewController viewController: UIViewController, animated: Bool, withUrl: URL?)
func start(onViewController viewController: UIViewController, animated: Bool, withPath: String?)
}
extension CoordinatorType {
public func start(onViewController viewController: UIViewController, animated: Bool) {
viewController.present(self.viewController(), animated: animated, completion: nil)
}
public func start(onViewController viewController: UIViewController, animated: Bool, withUrl: URL?) {
start(onViewController: viewController, animated: animated)
}
public func start(onViewController viewController: UIViewController, animated: Bool, withPath: String?) {
start(onViewController: viewController, animated: animated)
}
}
// MARK: - CoordinatorTypeDelegate
public protocol CoordinatorTypeDelegate: class {
func coordinatorDidFinish(_ coordinator: CoordinatorType)
}
extension CoordinatorTypeDelegate where Self: CoordinatorType {
public func coordinatorDidFinish(_ coordinator: CoordinatorType) {
guard let idx = childCoordinators.index(where: { $0 === coordinator }) else { return }
childCoordinators.remove(at: idx)
}
}
// MARK: - NavigationCoordinator
public protocol NavigationCoordinatorType: CoordinatorType {
weak var navigationController: UINavigationController? { get set }
func rootViewController() -> UIViewController
}
extension NavigationCoordinatorType {
public func navigationController() -> UINavigationController {
return viewController() as! UINavigationController
}
public func viewController() -> UIViewController {
let nav = UINavigationController()
start(onNavigationController: nav, animated: false)
return nav
}
public func start(onViewController viewController: UIViewController, animated: Bool) {
if let nav = viewController as? UINavigationController {
start(onNavigationController: nav, animated: animated)
} else {
let nav = UINavigationController()
start(onNavigationController: nav, animated: false)
viewController.present(nav, animated: animated, completion: nil)
}
}
private func start(onNavigationController navigationController: UINavigationController, animated: Bool) {
let root = rootViewController()
navigationController.pushViewController(root, animated: animated)
self.navigationController = navigationController
}
}
// MARK: - TabCoordinator
public protocol TabCoordinatorType: CoordinatorType {
weak var tabController: UITabBarController? { get set }
func rootViewControllers() -> [UIViewController]
}
extension TabCoordinatorType {
public func tabController() -> UITabBarController {
return viewController() as! UITabBarController
}
public func viewController() -> UIViewController {
let tab = UITabBarController()
start(onTabController: tab, animated: false)
return tab
}
public func start(onViewController viewController: UIViewController, animated: Bool) {
if let tab = viewController as? UITabBarController {
start(onTabController: tab, animated: animated)
} else {
let tab = UITabBarController()
start(onTabController: tab, animated: false)
viewController.present(tab, animated: true, completion: nil)
}
}
private func start(onTabController tabController: UITabBarController, animated: Bool) {
let roots = rootViewControllers()
tabController.setViewControllers(roots, animated: animated)
self.tabController = tabController
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment