Skip to content

Instantly share code, notes, and snippets.

@pixyzehn
Forked from AliSoftware/Coordinator.swift
Created April 9, 2016 08:07
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 pixyzehn/b0fc833c24a3714d0ea4e50347216bb4 to your computer and use it in GitHub Desktop.
Save pixyzehn/b0fc833c24a3714d0ea4e50347216bb4 to your computer and use it in GitHub Desktop.
Coordinators & StateMachine - Concept
struct Coordinator {
let window: UIWindow
let navCtrl: UINavigationController?
func start() {
presentWelcomeScreen()
}
private func presentWelcomeScreen() {
let vc = WelcomeScreenViewController() // Instanciate from code, XIB, Storyboard, whatever your jam is
vc.navTransitions = WelcomeScreenTransitions(
showHome: self.pushHomeScreen, // see private func below
showCreateAccountScreen: self.pushCreateAccountScreen
)
window.rootViewController = vc // or whatever
}
private func pushHomeScreen(user: User?) {
let vc = HomeScreenViewController() // Instanciate from code, XIB, Storyboard, whatever your jam is
vc.user = user // or inject a ViewModel here if you're doing MVVM, you get the idea
vc.navTransitions = HomeScreenTransitions(
showUserInfoScreen: {
// From Home, we *push* the UserInfoVC
self.navigationController.pushViewController(instanciateUserInfoScreen(user), animated: true, completion: nil)
}
showProductDetail: self.pushProductDetail // extracted in private function below
disconnectAndShowLoginScreen: self.presentLoginScreen // same
)
navCtrl = UINavigationController(rootViewController: vc)
window.rootViewController = navCtrl
}
private func pushProductDetail(product: Product) {
let vc = ProductDetailViewController() // Instanciate from code, XIB, Storyboard, whatever your jam is
vc.product = product // inject any object to the VC, like a ViewModel or whatever
vc.navTransitions = ProductDetailTransitions(
showUserInfoScreen: {
// But from ProductDetail VC, we *present* the UserInfoVC *modally*
self.presentViewController(instanciateUserInfoScreen(product.owner), animated: true, completion: nil)
}
back: { navCtrl?.popViewController(animated: true) }
)
navCtrl?.pushViewController(vc, animated: true) { _ in }
}
private func pushCreateAccountScreen() {
// Create and push a CreateAccountViewController and its CreateAccountTransitions struct
...
}
private func instanciateUserInfoScreen(user: User) -> UIViewController {
// Create, configure and return an UserDetailsViewController
...
}
}
struct HomeScreenTransitions {
let showUserInfoScreen: Void -> Void
let showProductDetail: Product -> Void
let disconnectAndShowLoginScreen: Void -> Void
}
class HomeScreenViewController: UIViewController {
var navTransitions: HomeScreenTransitions!
@IBAction func profileAction(_: AnyObject) {
navTransitions.showUserInfoScreen()
}
@IBAction func disconnectAction(_: AnyObject) {
confirm("Are you sure?") {
navTransitions.disconnectAndShowLoginScreen()
}
}
@objc func tableView(tableView: UITableView, didSelectRowAtIndexPath: NSIndexPath) {
let product = productsDataSource[indexPath.row]
navTransitions.showProductDetail(product)
}
}
struct Product {
let id: Int
let owner: User
...
}
struct ProductDetailTransitions {
let showUserInfoScreen: Void -> Void
let back: Void -> Void
}
class ProductDetailViewController: UIViewController {
var navTransitions: ProductDetailTransitions!
@IBAction func showProductOwner(_: AnyObject) {
navTransitions.showUserInfoScreen()
}
...
}
struct WelcomeScreenTransitions {
let showHome: User? -> Void
let showCreateAccountScreen: Void -> Void
}
class WelcomeScreenViewController: UIViewController {
var navTransitions: WelcomeScreenTransitions!
var webService: WebServiceAPI!
@IBAction func loginAction(_: AnyObject) {
webService.login(userTextField.text, passwordTextField.text) { (user: User?) in
navTransitions.showHome(user)
}
}
@IBAction func createAccountAction(_: AnyObject) {
navTransitions.showCreateAccountScreen()
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment