Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
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
520
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
480
端末上で CoreML のモデルをコンパイルする
yusuke1739
0
990
Other Decks in Programming
See All in Programming
The Rails Doctrine Decade
koic
2
590
IBM Bob でAI駆動開発『QC-Playbook』
ichirokano2
0
110
IBM Bob Dojo #1 仕様駆動開発入門
oniak3ibm
PRO
0
390
AWS CDKのカスタムリソースでContinuum(旧Security Agent)を実装した話 | Implementing Continuum (formerly Security Agent) via AWS CDK Custom Resource
akihisaikeda
2
150
Findy - エンジニア向け会社紹介/Findy Company Deck
findyinc
6
400k
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
210
Optunaを作ったときにやりたかったこと、その後 (2026/10/16, Optuna Meetup #3)
iwiwi
1
430
Herb in Rails 8.2: Your ERB views, now HTML-aware @ Kaigi on Rails 2026, Tokyo, Japan
marcoroth
2
220
Simple Storage Service(S3) is not simple
iwatsukayura
0
290
S3 TablesのIcebergデータに、AIエージェントからアクセスしてみた / 20261016developersio2026joetsu-accessing-iceberg-in-s3tables-via-agent
kasacchiful
PRO
0
150
現場と育てるRailsモデリング 〜Spreadsheetから始めたモデル設計〜
siroemk
2
590
ハーネス設計入門 〜 基礎知識の整理から実務へのステップアップ 〜
kinopeee
28
32k
Featured
See All Featured
The Organizational Zoo: Understanding Human Behavior Agility Through Metaphoric Constructive Conversations (based on the works of Arthur Shelley, Ph.D)
kimpetersen
PRO
0
500
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
330
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
750
AI: The stuff that nobody shows you
jnunemaker
PRO
10
1.2k
Kristin Tynski - Automating Marketing Tasks With AI
techseoconnect
PRO
0
550
Put a Button on it: Removing Barriers to Going Fast.
kastner
60
4.6k
A Tale of Four Properties
chriscoyier
163
24k
Side Projects
sachag
456
43k
Designing for humans not robots
tammielis
254
26k
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
550
Become a Pro
speakerdeck
PRO
31
6.3k
How Fast Is Fast Enough? [PerfNow 2025]
tammyeverts
3
940
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