Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Introduction of coordinator pattern

ysk-tngc
February 16, 2018

Introduction of coordinator pattern

ysk-tngc

February 16, 2018
Tweet

More Decks by ysk-tngc

Other Decks in Programming

Transcript

  1. .7̋̋ͷ̋̋͸୭͕؅ཧ͢Δͷ͔໰୊ final class CurrentViewController: UIViewController { // 1. ΠϕϯτΛड͚औΔ @IBAction

    func nextButtonTapped(_ sender: UIButton) { // 2. ࣍ͷը໘Λੜ੒ let nextVC = UIStoryboard(name: "Next", bundle: nil) .instantiateInitialViewController() as! NextViewController // 3. ࣍ͷը໘ʹඞཁͳ ViewModel Λੜ੒ nextVC.viewModel = NextViewModel() // 4. ը໘ભҠ self.navigationController?.pushViewController(nextVC, animated: true) } }
  2. .7̋̋ͷ̋̋͸୭͕؅ཧ͢Δͷ͔໰୊ final class CurrentViewController: UIViewController { // 1. ΠϕϯτΛड͚औΔ @IBAction

    func nextButtonTapped(_ sender: UIButton) { // 2. ࣍ͷը໘Λੜ੒ let nextVC = UIStoryboard(name: "Next", bundle: nil) .instantiateInitialViewController() as! NextViewController // 3. ࣍ͷը໘ʹඞཁͳ ViewModel Λੜ੒ nextVC.viewModel = NextViewModel() // 4. ը໘ભҠ self.navigationController?.pushViewController(nextVC, animated: true) } } Ҏ֎͸7JFXͷ࢓ࣄͰ͸ͳ͍ͷͰ͸ʁ
  3. class Coordinator { // ਌ Coordinator private(set) weak var parentCoodinator:

    Coordinator? // ࢠ Coordinator private(set) var childCoordinators: [Coordinator] = [] /// Coordinator Λελʔτ (ը໘ભҠॲཧ) /// ࢠΫϥεͰඞͣ override ͢Δ func start() { fatalError("This method must be overrided.") } /// Coordinator Λऴྃ func finish() { removeFromParentCoodinator() } /// ࣍ͷ Coordinator Λ childCoordinators ʹ֨ೲ /// /// - Parameter childCoordinator: ࣍ͷ Coordinator func addChildCoordinator(_ childCoordinator: Coordinator) { childCoordinators.append(childCoordinator) childCoordinator.parentCoodinator = self } /// ࣗ਎Λ਌͔Β࡟আ͢Δ private func removeFromParentCoodinator() { guard let parent = parentCoodinator else { return } for (index, element) in parent.childCoordinators.enumerated() { if element === self { parent.childCoordinators.remove(at: index) break } } } }
  4. 'JSTU7JFX$POUSPMMFSTXJGU protocol FirstViewControllerDelegate: class { func firstViewController(_ firstViewController: FirstViewController, didTap

    action: FirstViewController.Action) } final class FirstViewController: UIViewController { enum Action { case next } var viewModel: FirstViewModel! weak var delegate: FirstViewControllerDelegate? @IBAction func nextButtonTapped(_ sender: UIButton) { delegate?.firstViewController(self, didTap: .next) } }
  5. 'JSTU$PPSEJOBUPSTXJGU final class FirstCoordinator: Coordinator { private let navigationController: UINavigationController

    init(navigationController: UINavigationController) { self.navigationController = navigationController } override func start() { let vc = UIStoryboard(name: "First", bundle: nil) .instantiateInitialViewController() as! FirstViewController vc.delegate = self navigationController.setViewControllers([vc], animated: false) } } extension FirstCoordinator: FirstViewControllerDelegate { func firstViewController(_ firstViewController: FirstViewController, didTap action: FirstViewController.Action) { switch action { case .next: let nextCoordinator = SecondCoordinator(parentViewController: navigationController) addChildCoordinator(nextCoordinator) nextCoordinator.start() } } }
  6. @UIApplicationMain class AppDelegate: UIResponder, UIApplicationDelegate { var window: UIWindow? private

    var firstCoordinator: FirstCoordinator! func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool { // ͍ͭ΋Ͳ͓Γ Window ͱ RootViewController Λ༻ҙ͢Δ let window = UIWindow(frame: UIScreen.main.bounds) let rootNavigationController = UINavigationController() window.rootViewController = rootNavigationController window.makeKeyAndVisible() // ࠷ॳͷ Coordinator Λ start let firstCoordinator = FirstCoordinator(navigationController: rootNavigationController) firstCoordinator.start() self.firstCoordinator = firstCoordinator self.window = window return true } } "QQ%FMFHBUFTXJGU
  7. 'JSTU$PPSEJOBUPSTXJGU final class FirstCoordinator: Coordinator { private let navigationController: UINavigationController

    init(navigationController: UINavigationController) { self.navigationController = navigationController } override func start() { let vc = UIStoryboard(name: "First", bundle: nil) .instantiateInitialViewController() as! FirstViewController vc.delegate = self navigationController.setViewControllers([vc], animated: false) } } extension FirstCoordinator: FirstViewControllerDelegate { func firstViewController(_ firstViewController: FirstViewController, didTap action: FirstViewController.Action) { switch action { case .next: let nextCoordinator = SecondCoordinator(parentViewController: navigationController) addChildCoordinator(nextCoordinator) nextCoordinator.start() } } }
  8. 'JSTU$PPSEJOBUPSTXJGU final class FirstCoordinator: Coordinator { private let navigationController: UINavigationController

    init(navigationController: UINavigationController) { self.navigationController = navigationController } override func start() { let vc = UIStoryboard(name: "First", bundle: nil) .instantiateInitialViewController() as! FirstViewController vc.delegate = self navigationController.setViewControllers([vc], animated: false) } } extension FirstCoordinator: FirstViewControllerDelegate { func firstViewController(_ firstViewController: FirstViewController, didTap action: FirstViewController.Action) { switch action { case .next: let nextCoordinator = SecondCoordinator(parentViewController: navigationController) addChildCoordinator(nextCoordinator) nextCoordinator.start() } } }
  9. final class SecondCoordinator: Coordinator { private let parentViewController: UIViewController private

    var navigationController: UINavigationController! init(parentViewController: UIViewController) { self.parentViewController = parentViewController } override func start() { let vc = UIStoryboard(name: "Second", bundle: nil) .instantiateInitialViewController() as! SecondViewController vc.delegate = self let navigationVC = UINavigationController(rootViewController: vc) parentViewController.present(navigationVC, animated: true, completion: nil) self.navigationController = navigationVC } } extension SecondCoordinator: SecondViewControllerDelegate { func secondViewController(_ secondViewController: SecondViewController, didTap action: SecondViewController.Action) { switch action { case .close: self.navigationController.dismiss(animated: true, completion: { [weak self] in self?.finish() }) } } } 4FDPOE$PPSEJOBUPSTXJGU
  10. protocol SecondViewControllerDelegate: class { func secondViewController(_ secondViewController: SecondViewController, didTap action:

    SecondViewController.Action) } final class SecondViewController: UIViewController { enum Action { case close } var viewModel: SecondViewModel! weak var delegate: SecondViewControllerDelegate? override func viewDidLoad() { super.viewDidLoad() navigationItem.leftBarButtonItem = UIBarButtonItem(title: "ด͡Δ", style: .done, target: self, action: #selector(closeButtonTapped(_:))) } @objc private func closeButtonTapped(_ sender: UIBarButtonItem) { delegate?.secondViewController(self, didTap: .close) } } 4FDPOE7JFX$POUSPMMFSTXJGU
  11. final class SecondCoordinator: Coordinator { private let parentViewController: UIViewController private

    var navigationController: UINavigationController! init(parentViewController: UIViewController) { self.parentViewController = parentViewController } override func start() { let vc = UIStoryboard(name: "Second", bundle: nil) .instantiateInitialViewController() as! SecondViewController vc.delegate = self let navigationVC = UINavigationController(rootViewController: vc) parentViewController.present(navigationVC, animated: true, completion: nil) self.navigationController = navigationVC } } extension SecondCoordinator: SecondViewControllerDelegate { func secondViewController(_ secondViewController: SecondViewController, didTap action: SecondViewController.Action) { switch action { case .close: self.navigationController.dismiss(animated: true, completion: { [weak self] in self?.finish() }) } } } 4FDPOE$PPSEJOBUPSTXJGU