Coordinator Swift
- Tram Ho
Bối cảnh
Bạn đã bao giờ ở trong một tình huống, nơi mà các của bạn trở nên quá giống nhau và phụ thuộc vào nhau. Và điều hướng của bạn nằm rải rác trên mã của bạn.
Bạn cũng có thể đã nghe nói về vấn đề ViewController lớn. có liên quan đến thực tế là ViewController trong mẫu MVC thường làm quá nhiều thứ, bao gồm cả mã thiết lập chế độ xem. theo cách mà bộ điều khiển chế độ xem thực sự trở thành một chế độ xem (và hơn thế nữa…)
Một trong những tác vụ mà ViewController không được thực hiện là quản lý điều hướng màn hình(screens navigation) và luồng ứng dụng.
Coordinator là gì?
Nó là một object xử lý navigation flow, chung chuyển Data giữa các ViewController và không có liên quan gì đến business logic.
Sử dụng coordinator pattern giúp chúng ta giảm bớt công việc cho navgation từ viewcontroller của chúng ta, giúp chúng dễ quản lý và tái sử dụng tốt hơn, trong khi cho phép chúng ta điều chỉnh luồng ứng dụng bất kì lúc nào cần.
Nói cách khác: Thay vì đẩy và trình bày các ViewControllers của bạn từ các bộ điều khiển chế độ xem khác. Tất cả ViewController sẽ được quản lý bởi các Coordinator
Do đó, các ViewController sẽ bị cô lập và vô hình với nhau, đồng thời có thể được sử dụng lại một cách dễ dàng.
Như minh họa trên lược đồ trên. Mô hình Coordinator có thể được mô tả như sau:
- có thể có một hoặc nhiều ViewController theo Coordinator.
- Mỗi bộ điều phối hiển thị (các) viewController của nó bằng cách sử dụng một phương thức thường được gọi là start() .
- Mỗi ViewController có 1 tham chiếu uỷ nhiệm (delegate) đến coordinator của nó.
- Mỗi Coordinator có 1 loạt các coordinator con (ChildCoordinators).
- Mỗi Coordinator con có 1 tham chiếu delegate cho Coordinator cha
Demo Coordinator
Ở đây ta có 2 Coordinator và 3 ViewController để cho thấy rằng 1 coordinator có thế có 1 hoặc nhiều View
Tạo một dự án với 3 ViewController: FirstViewController, SecondViewController và ThirdViewController.
Trên mỗi ViewController thêm 1 nút để điều hướng đến ViewController khác
Đầu tiên ta sẽ tạo một giao thức Coordinator. Với 1 mảng Coordinator và 1 phương thức init nhận 1 bộ điều khiển hướng(navigationController) làm tham số.
1 2 3 4 5 6 7 8 9 10 | <span class="token keyword">public</span> <span class="token keyword">protocol</span> <span class="token builtin">Coordinator</span> <span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> childCoordinators<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token builtin">Coordinator</span><span class="token punctuation">]</span> <span class="token punctuation">{</span> <span class="token keyword">get</span> <span class="token keyword">set</span> <span class="token punctuation">}</span> <span class="token comment">// All coordinators will be initilised with a navigation controller</span> <span class="token keyword">init</span><span class="token punctuation">(</span>navigationController<span class="token punctuation">:</span><span class="token builtin">UINavigationController</span><span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> |
FirstCoordinator quản lý FirstViewController. Với việc triển khai phương pháp bắt đầu, thêm FirstViewController và FirstCoordinator:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | <span class="token keyword">import</span> <span class="token builtin">UIKit</span> <span class="token keyword">class</span> <span class="token class-name">FirstCoordinator</span><span class="token punctuation">:</span> <span class="token builtin">Coordinator</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> childCoordinators<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token builtin">Coordinator</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token keyword">unowned</span> <span class="token keyword">let</span> navigationController<span class="token punctuation">:</span><span class="token builtin">UINavigationController</span> <span class="token keyword">required</span> <span class="token keyword">init</span><span class="token punctuation">(</span>navigationController<span class="token punctuation">:</span> <span class="token builtin">UINavigationController</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">self</span><span class="token punctuation">.</span>navigationController <span class="token operator">=</span> navigationController <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> firstViewController <span class="token punctuation">:</span> <span class="token builtin">FirstViewController</span> <span class="token operator">=</span> <span class="token function">FirstViewController</span><span class="token punctuation">(</span><span class="token punctuation">)</span> firstViewController<span class="token punctuation">.</span>delegate <span class="token operator">=</span> <span class="token keyword">self</span> <span class="token keyword">self</span><span class="token punctuation">.</span>navigationController<span class="token punctuation">.</span>viewControllers <span class="token operator">=</span> <span class="token punctuation">[</span>firstViewController<span class="token punctuation">]</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">extension</span> <span class="token builtin">FirstCoordinator</span><span class="token punctuation">:</span> <span class="token builtin">FirstViewControllerDelegate</span> <span class="token punctuation">{</span> <span class="token comment">// Navigate to next page</span> <span class="token keyword">func</span> <span class="token function">navigateToNextPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> secondCoordinator <span class="token operator">=</span> <span class="token function">SecondCoordinator</span><span class="token punctuation">(</span>navigationController<span class="token punctuation">:</span> navigationController<span class="token punctuation">)</span> secondCoordinator<span class="token punctuation">.</span>delegate <span class="token operator">=</span> <span class="token keyword">self</span> childCoordinators<span class="token punctuation">.</span><span class="token function">append</span><span class="token punctuation">(</span>secondCoordinator<span class="token punctuation">)</span> secondCoordinator<span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">extension</span> <span class="token builtin">FirstCoordinator</span><span class="token punctuation">:</span> <span class="token builtin">BackToFirstViewControllerDelegate</span> <span class="token punctuation">{</span> <span class="token comment">// Back from third page</span> <span class="token keyword">func</span> <span class="token function">navigateBackToFirstPage</span><span class="token punctuation">(</span>newOrderCoordinator<span class="token punctuation">:</span> <span class="token builtin">SecondCoordinator</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> navigationController<span class="token punctuation">.</span><span class="token function">popToRootViewController</span><span class="token punctuation">(</span>animated<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">)</span> childCoordinators<span class="token punctuation">.</span><span class="token function">removeLast</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
FirstCoordinator có 2 extension, 1 là sử dụng để điều hướng tới ViewController tiếp theo hai là dùng để điều hướng trở lại FirstCoordinator.
Chúng ta cần phải cập nhật mảng coordinator con với ngăn xếp là coordinator
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token keyword">var</span> window<span class="token punctuation">:</span> <span class="token builtin">UIWindow</span><span class="token operator">?</span> <span class="token comment">// Make the first coordinator with a strong reference</span> <span class="token keyword">var</span> fisrtCoordinator <span class="token punctuation">:</span> <span class="token builtin">FirstCoordinator</span><span class="token operator">?</span> <span class="token keyword">func</span> <span class="token function">application</span><span class="token punctuation">(</span><span class="token number">_</span> application<span class="token punctuation">:</span> <span class="token builtin">UIApplication</span><span class="token punctuation">,</span> didFinishLaunchingWithOptions launchOptions<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token builtin">UIApplicationLaunchOptionsKey</span><span class="token punctuation">:</span> <span class="token builtin">Any</span><span class="token punctuation">]</span><span class="token operator">?</span><span class="token punctuation">)</span> <span class="token operator">-</span><span class="token operator">></span> <span class="token builtin">Bool</span> <span class="token punctuation">{</span> window <span class="token operator">=</span> <span class="token function">UIWindow</span><span class="token punctuation">(</span>frame<span class="token punctuation">:</span> <span class="token builtin">UIScreen</span><span class="token punctuation">.</span>main<span class="token punctuation">.</span>bounds<span class="token punctuation">)</span> window<span class="token operator">?</span><span class="token punctuation">.</span>rootViewController <span class="token operator">=</span> <span class="token function">UINavigationController</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token comment">// Initialise the first coordinator with the main navigation controller</span> fisrtCoordinator <span class="token operator">=</span> <span class="token function">FirstCoordinator</span><span class="token punctuation">(</span>navigationController<span class="token punctuation">:</span> window<span class="token operator">?</span><span class="token punctuation">.</span>rootViewController <span class="token keyword">as</span><span class="token operator">!</span> <span class="token builtin">UINavigationController</span><span class="token punctuation">)</span> <span class="token comment">// The start method will actually display the main view</span> fisrtCoordinator<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> window<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">makeKeyAndVisible</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">return</span> <span class="token boolean">true</span> <span class="token punctuation">}</span> |
Sau đó thay vì trực tiếp tạo phương thức trong mainController. chúng ta tạo FirstCoordinator với tham số navigationController. và phương thức start() sẽ phụ trách hiển thị ViewController đầu tiên.
Đối với AppDelegate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | <span class="token keyword">public</span> <span class="token keyword">protocol</span> <span class="token builtin">FirstViewControllerDelegate</span><span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">{</span> <span class="token keyword">func</span> <span class="token function">navigateToNextPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">FirstViewController</span><span class="token punctuation">:</span> <span class="token builtin">UIViewController</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">weak</span> <span class="token keyword">var</span> delegate<span class="token punctuation">:</span> <span class="token builtin">FirstViewControllerDelegate</span><span class="token operator">?</span> <span class="token keyword">override</span> <span class="token keyword">func</span> <span class="token function">viewDidLoad</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">viewDidLoad</span><span class="token punctuation">(</span><span class="token punctuation">)</span> title <span class="token operator">=</span> <span class="token string">"FirstViewController"</span> <span class="token punctuation">}</span> <span class="token atrule">@IBAction</span> <span class="token keyword">func</span> <span class="token function">goToSecondPageAction</span><span class="token punctuation">(</span><span class="token number">_</span> sender<span class="token punctuation">:</span> <span class="token builtin">Any</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">self</span><span class="token punctuation">.</span>delegate<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">navigateToNextPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Đối với SceneDelegate
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | <span class="token keyword">var</span> window<span class="token punctuation">:</span> <span class="token builtin">UIWindow</span><span class="token operator">?</span> <span class="token keyword">var</span> fisrtCoordinator <span class="token punctuation">:</span> <span class="token builtin">FirstCoordinator</span><span class="token operator">?</span> <span class="token keyword">func</span> <span class="token function">scene</span><span class="token punctuation">(</span><span class="token number">_</span> scene<span class="token punctuation">:</span> <span class="token builtin">UIScene</span><span class="token punctuation">,</span> willConnectTo session<span class="token punctuation">:</span> <span class="token builtin">UISceneSession</span><span class="token punctuation">,</span> options connectionOptions<span class="token punctuation">:</span> <span class="token builtin">UIScene</span><span class="token punctuation">.</span><span class="token builtin">ConnectionOptions</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">guard</span> <span class="token keyword">let</span> windowScene <span class="token operator">=</span> <span class="token punctuation">(</span>scene <span class="token keyword">as</span><span class="token operator">?</span> <span class="token builtin">UIWindowScene</span><span class="token punctuation">)</span> <span class="token keyword">else</span> <span class="token punctuation">{</span> <span class="token keyword">return</span> <span class="token punctuation">}</span> window <span class="token operator">=</span> <span class="token function">UIWindow</span><span class="token punctuation">(</span>frame<span class="token punctuation">:</span> windowScene<span class="token punctuation">.</span>coordinateSpace<span class="token punctuation">.</span>bounds<span class="token punctuation">)</span> window<span class="token operator">?</span><span class="token punctuation">.</span>windowScene <span class="token operator">=</span> windowScene window<span class="token operator">?</span><span class="token punctuation">.</span>rootViewController <span class="token operator">=</span> <span class="token function">UINavigationController</span><span class="token punctuation">(</span><span class="token punctuation">)</span> fisrtCoordinator <span class="token operator">=</span> <span class="token function">FirstCoordinator</span><span class="token punctuation">(</span>navigationController<span class="token punctuation">:</span> window<span class="token operator">?</span><span class="token punctuation">.</span>rootViewController <span class="token keyword">as</span><span class="token operator">!</span> <span class="token builtin">UINavigationController</span><span class="token punctuation">)</span> fisrtCoordinator<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> window<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">makeKeyAndVisible</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> |
Để điều hướng đến ViewController tiếp theo. Chúng ta sẽ phải gọi Coordinator được đại diện bởi FirstViewControllerDelegate.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 | <span class="token keyword">protocol</span> <span class="token builtin">BackToFirstViewControllerDelegate</span><span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">{</span> <span class="token keyword">func</span> <span class="token function">navigateBackToFirstPage</span><span class="token punctuation">(</span>newOrderCoordinator<span class="token punctuation">:</span> <span class="token builtin">SecondCoordinator</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">SecondCoordinator</span><span class="token punctuation">:</span> <span class="token builtin">Coordinator</span> <span class="token punctuation">{</span> <span class="token keyword">var</span> childCoordinators<span class="token punctuation">:</span> <span class="token punctuation">[</span><span class="token builtin">Coordinator</span><span class="token punctuation">]</span> <span class="token operator">=</span> <span class="token punctuation">[</span><span class="token punctuation">]</span> <span class="token keyword">unowned</span> <span class="token keyword">let</span> navigationController<span class="token punctuation">:</span><span class="token builtin">UINavigationController</span> <span class="token comment">// We use this delegate to keep a reference to the parent coordinator</span> <span class="token keyword">weak</span> <span class="token keyword">var</span> delegate<span class="token punctuation">:</span> <span class="token builtin">BackToFirstViewControllerDelegate</span><span class="token operator">?</span> <span class="token keyword">required</span> <span class="token keyword">init</span><span class="token punctuation">(</span>navigationController<span class="token punctuation">:</span> <span class="token builtin">UINavigationController</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">self</span><span class="token punctuation">.</span>navigationController <span class="token operator">=</span> navigationController <span class="token punctuation">}</span> <span class="token keyword">func</span> <span class="token function">start</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> secondViewController <span class="token punctuation">:</span> <span class="token builtin">SecondViewController</span> <span class="token operator">=</span> <span class="token function">SecondViewController</span><span class="token punctuation">(</span><span class="token punctuation">)</span> secondViewController<span class="token punctuation">.</span>delegate <span class="token operator">=</span> <span class="token keyword">self</span> <span class="token keyword">self</span><span class="token punctuation">.</span>navigationController<span class="token punctuation">.</span><span class="token function">pushViewController</span><span class="token punctuation">(</span>secondViewController<span class="token punctuation">,</span> animated<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> <span class="token keyword">extension</span> <span class="token builtin">SecondCoordinator</span> <span class="token punctuation">:</span> <span class="token builtin">SecondViewControllerDelegate</span> <span class="token punctuation">{</span> <span class="token comment">// Navigate to third page</span> <span class="token keyword">func</span> <span class="token function">navigateToThirdPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">let</span> thirdViewController <span class="token punctuation">:</span> <span class="token builtin">ThirdViewController</span> <span class="token operator">=</span> <span class="token function">ThirdViewController</span><span class="token punctuation">(</span><span class="token punctuation">)</span> thirdViewController<span class="token punctuation">.</span>delegate <span class="token operator">=</span> <span class="token keyword">self</span> <span class="token keyword">self</span><span class="token punctuation">.</span>navigationController<span class="token punctuation">.</span><span class="token function">pushViewController</span><span class="token punctuation">(</span>thirdViewController<span class="token punctuation">,</span> animated<span class="token punctuation">:</span> <span class="token boolean">true</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token comment">// Navigate to first page</span> <span class="token keyword">func</span> <span class="token function">navigateToFirstPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">self</span><span class="token punctuation">.</span>delegate<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">navigateBackToFirstPage</span><span class="token punctuation">(</span>newOrderCoordinator<span class="token punctuation">:</span> <span class="token keyword">self</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Như được đề cập ở trên. Một coordinator có thể quản lý một hoặc nhiều ViewController. Vì vậy, ở đây SecondCoordinator sẽ xử lý cả SecondViewController và ThirdViewControllers.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 | <span class="token keyword">public</span> <span class="token keyword">protocol</span> <span class="token builtin">SecondViewControllerDelegate</span><span class="token punctuation">:</span> <span class="token keyword">class</span> <span class="token punctuation">{</span> <span class="token keyword">func</span> <span class="token function">navigateToFirstPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token keyword">func</span> <span class="token function">navigateToThirdPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token keyword">class</span> <span class="token class-name">SecondViewController</span><span class="token punctuation">:</span> <span class="token builtin">UIViewController</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">weak</span> <span class="token keyword">var</span> delegate<span class="token punctuation">:</span> <span class="token builtin">SecondViewControllerDelegate</span><span class="token operator">?</span> <span class="token keyword">override</span> <span class="token keyword">func</span> <span class="token function">viewDidLoad</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">viewDidLoad</span><span class="token punctuation">(</span><span class="token punctuation">)</span> title <span class="token operator">=</span> <span class="token string">"SecondViewController"</span> <span class="token comment">// Use custom back button to pass through coordinator.</span> <span class="token keyword">let</span> backButton <span class="token operator">=</span> <span class="token function">UIBarButtonItem</span><span class="token punctuation">(</span>title<span class="token punctuation">:</span> <span class="token string">"Back"</span><span class="token punctuation">,</span> style<span class="token punctuation">:</span> <span class="token punctuation">.</span>plain<span class="token punctuation">,</span> target<span class="token punctuation">:</span> <span class="token keyword">self</span><span class="token punctuation">,</span> action<span class="token punctuation">:</span> #<span class="token function">selector</span><span class="token punctuation">(</span>navigateBackToFirstpage<span class="token punctuation">)</span><span class="token punctuation">)</span> <span class="token keyword">self</span><span class="token punctuation">.</span>navigationItem<span class="token punctuation">.</span>leftBarButtonItem <span class="token operator">=</span> backButton <span class="token punctuation">}</span> <span class="token atrule">@objc</span> <span class="token keyword">func</span> <span class="token function">navigateBackToFirstpage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">self</span><span class="token punctuation">.</span>delegate<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">navigateToFirstPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token atrule">@IBAction</span> <span class="token keyword">func</span> <span class="token function">navigateToThirdPageAction</span><span class="token punctuation">(</span><span class="token number">_</span> sender<span class="token punctuation">:</span> <span class="token builtin">Any</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">self</span><span class="token punctuation">.</span>delegate<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">navigateToThirdPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Đầu tiên ta tạo 1 nút quay lại tuỳ chỉnh gọi 1 phương thức coordinator điều phối NavigateToFirstpage: Lưu ý quan trọng : khi chuyển đổi giữa các coordinator. nút quay lại của bộ điều khiển điều hướng mặc định sẽ phá vỡ logic của bộ điều phối nếu hành động không bị ghi đè. chúng ta hoàn toàn nên gọi hành động quay lại của chính mình bằng cách sử dụng phương thức coordinator để đảm bảo mảng coordinator con được cập nhật tốt
Và sau đó chúng tôi thêm phương thức khác để chuyển đến ThirdViewController:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | <span class="token keyword">public</span> <span class="token keyword">class</span> <span class="token class-name">ThirdViewController</span><span class="token punctuation">:</span> <span class="token builtin">UIViewController</span> <span class="token punctuation">{</span> <span class="token keyword">public</span> <span class="token keyword">weak</span> <span class="token keyword">var</span> delegate<span class="token punctuation">:</span> <span class="token builtin">SecondViewControllerDelegate</span><span class="token operator">?</span> <span class="token keyword">override</span> <span class="token keyword">public</span> <span class="token keyword">func</span> <span class="token function">viewDidLoad</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">super</span><span class="token punctuation">.</span><span class="token function">viewDidLoad</span><span class="token punctuation">(</span><span class="token punctuation">)</span> title <span class="token operator">=</span> <span class="token string">"ThirdViewController"</span> <span class="token punctuation">}</span> <span class="token atrule">@IBAction</span> <span class="token keyword">func</span> <span class="token function">navigateToFirstPageAction</span><span class="token punctuation">(</span><span class="token number">_</span> sender<span class="token punctuation">:</span> <span class="token builtin">Any</span><span class="token punctuation">)</span> <span class="token punctuation">{</span> <span class="token keyword">self</span><span class="token punctuation">.</span>delegate<span class="token operator">?</span><span class="token punctuation">.</span><span class="token function">navigateToFirstPage</span><span class="token punctuation">(</span><span class="token punctuation">)</span> <span class="token punctuation">}</span> <span class="token punctuation">}</span> |
Và cuối cùng, ThirdViewController gọi người đại diện của nó delegate (SecondCoordinator) để điều hướng về FirstViewController. Và ở đây không cần ghi đè nút quay lại navigationController, vì nó sẽ không thay đổi coordinator hiện tại.
Và bằng cách này chúng ta có thể điều hướng vòng lặp: FirstViewController -> SecondViewController -> ThirdViewController.