Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Features
Speaker Deck
PRO
Sign in
Sign up for free
Search
Search
Introduction of coordinator pattern
Search
Sponsored
·
Ship Features Fearlessly
Turn features on and off without deploys. Used by thousands of Ruby developers.
→
ysk-tngc
February 16, 2018
Programming
510
0
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Introduction of coordinator pattern
https://mobileact.connpass.com/event/77509/
ysk-tngc
February 16, 2018
More Decks by ysk-tngc
See All by ysk-tngc
CoreML のモデルを iOS 端末上で コンパイルするときの注意点
yusuke1739
0
470
端末上で CoreML のモデルをコンパイルする
yusuke1739
0
980
Other Decks in Programming
See All in Programming
仕様駆動開発へのトライを機に チームに適合する手法を模索し続けている話
freee
PRO
0
620
「人を評価する AI」の設計と実装
ryoyanara
0
240
PostgreSQL 18で考えるUUID主キー
kazuhiro1982
0
500
Claude Code全社展開のためにやったことn選~プラグイン302個・コミッター271人を支えるために~
kenchan
5
1.8k
AIの中の人になってみる
htkym
0
120
KotlinConf Extended South Korea 2026 Keynote
l2hyunwoo
0
120
メールのエイリアス機能を履き違えない
isshinfunada
0
250
170k Jobs a Day on GKE: Scaling Mercari's CI Platform - and What's Next for AI-Native Development
junyaokabe
0
120
レビュー履歴をAIに食わせて、 Compose移行を加速するs
shihochan
0
210
バグを直したら useEffect が消えた
colorful12
3
700
Flow は今どうなっているか
mizdra
PRO
0
720
komatsuna「分散システムにおけるバグ分析手法」
komatsunaqa
0
280
Featured
See All Featured
How to Talk to Developers About Accessibility
jct
2
520
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
19k
Visualizing Your Data: Incorporating Mongo into Loggly Infrastructure
mongodb
49
10k
Design of three-dimensional binary manipulators for pick-and-place task avoiding obstacles (IECON2024)
konakalab
0
550
The Art of Delivering Value - GDevCon NA Keynote
reverentgeek
16
2.1k
The Language of Interfaces
destraynor
162
27k
Bioeconomy Workshop: Dr. Julius Ecuru, Opportunities for a Bioeconomy in West Africa
akademiya2063
PRO
1
280
How People are Using Generative and Agentic AI to Supercharge Their Products, Projects, Services and Value Streams Today
helenjbeal
1
280
Fight the Zombie Pattern Library - RWD Summit 2016
marcelosomers
234
17k
State of Search Keynote: SEO is Dead Long Live SEO
ryanjones
0
250
Why Mistakes Are the Best Teachers: Turning Failure into a Pathway for Growth
auna
0
220
Sharpening the Axe: The Primacy of Toolmaking
bcantrill
46
3k
Transcript
$PPSEJOBUPS1BUUFSOͷհ
ઃܭύλʔϯ৭ʑ
ઃܭύλʔϯ৭ʑ .PEFM7JFX$POUSPMMFS .PEFM7JFX1SFTFOUFS .PEFM7JFX7JFX.PEFM $MFBO"SDIJUFDUVSF %PNBJO%SJWFO%FTJHO
ઃܭύλʔϯ৭ʑ .PEFM7JFX$POUSPMMFS .PEFM7JFX1SFTFOUFS .PEFM7JFX7JFX.PEFM $MFBO"SDIJUFDUVSF %PNBJO%SJWFO%FTJHO େࡶʹݴ͏ͱɺJ04 "OESPJE։ൃͰʜ 7JFXͱʮͦΕҎ֎ʯʹ͚ͯɺ ʮͦΕҎ֎ʯΛͲ͏ઃܭ͢Δ͔
.7̋̋ͷ̋̋୭͕ཧ͢Δͷ͔
.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) } }
.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ͷࣄͰͳ͍ͷͰʁ
$PPSEJOBUPS1BUUFSO
$PPSEJOBUPS1BUUFSO ը໘ભҠॲཧΛߦ͏$PPSEJOBUPSΫϥε 7JFX$POUSPMMFS ͷॲཧΛ $PPSEJOBUPSʹσϦήʔτ
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 } } } }
αϯϓϧΞϓϦ
'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) } }
'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() } } }
@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
'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() } } }
'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() } } }
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
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
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
ิͳͲ $PPSEJOBUPS/BWJHBUJPO$POUSPMMFS 5BC#BS$POUSPMMFSͷ୯ҐͰ࡞Δ ϝϦοτɾσϝϦοτ 7JFX$POUSPMMFSͷίʔυΛγϯϓϧʹͰ͖Δ શମͷίʔυྔ͕ଟ͘ͳΓ͕ͪ
ࢀߟจݙ IUUQLIBOMPVDPNDPPSEJOBUPSTSFEVY IUUQTHJUIVCDPN"OESFZ1BOPW"QQMJDBUJPO$PPSEJOBUPS αϯϓϧίʔυ IUUQTHJUIVCDPNZTLUOHD4JNQMF$PPSEJOBUPS1BUUFSO