Coordinator Swift
- Tram Ho
Background
Have you ever been in a situation where your friends become too similar and dependent on each other. And your navigation is scattered across your code.
You may also have heard of the big ViewController problem. is related to the fact that the ViewController in the MVC pattern often does too much, including the view setting code. in the way that the view controller actually becomes a view (and more …)
One of the tasks that ViewController does not perform is the management of screens navigation and application flow.
What is the coordinator?
It is an object that handles navigation flow, generally transfers Data between ViewController and has nothing to do with the business logic.
Using the coordinator pattern helps us ease the work of navgation from our viewcontroller, making them easier to manage and reuse, while allowing us to adjust the application flow at any time.
In other words: Instead of pushing and presenting your ViewControllers from other view controllers. All ViewController will be managed by the Coordinators
Therefore, the ViewController will be isolated and invisible from each other, and can be easily reused.
As illustrated in the above diagram. The Coordinator model can be described as follows:
- there may be one or more ViewController according to the Coordinator.
- Each coordinator displays its viewController (s) using a method commonly referred to as start ().
- Each ViewController has 1 delegate reference (delegate) to its coordinator.
- Each Coordinator has a series of child coordinators (ChildCoordinators).
- Each child coordinator has 1 delegate reference for the parent Coordinator
Demo Coordinator
Here we have 2 Coordinator and 3 ViewController to show that 1 coordinator can have 1 or more View
Create a project with 3 ViewController: FirstViewController, SecondViewController and ThirdViewController.
On each ViewController add 1 button to navigate to other ViewController
First we will create a Coordinator protocol. With 1 Coordinator array and 1 init method takes 1 direction controller (navigationController) as parameter.
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 manages the FirstViewController. With the method implementation start, add FirstViewController and 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 has 2 extensions, 1 is used to navigate to ViewController followed by the second is used to navigate back to FirstCoordinator.
We need to update the child coordinator array with the coordinator stack
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> |
Then instead of directly creating the method in mainController. we create a FirstCoordinator with the navigationController parameter. and the start () method will be in charge of displaying the ViewController first.
For 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> |
For 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> |
To navigate to the next ViewController. We will have to call the Coordinator represented by 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> |
As mentioned above. One coordinator can manage one or more ViewController. So here SecondCoordinator will handle both SecondViewController and 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> |
First we create a custom back button that calls a coordinator coordinator method NavigateToFirstpage: Important note: when switching between coordinators. the default navigation controller’s back button will break the dispatcher’s logic if the action is not overwritten. we should absolutely call our own return action using the coordinator method to make sure the child coordinator array is updated well.
And then we add another method to pass to the 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> |
And finally, the ThirdViewController calls its delegate delegate (SecondCoordinator) to navigate back to the FirstViewController. And here there is no need to override the navigationController return button, as it will not change the current coordinator.
And this way we can navigate the loop: FirstViewController -> SecondViewController -> ThirdViewController.