Chapter 23: Coordinator Pattern (Bug)

Hi, finally starting to understand the coordinator pattern!

There is a bug in the final app:

When you swipe down to manually dismiss the modally presented ‘VisitType’ view controller, the performOnDismissed method is never triggered. The child coordinator is never removed.

Pressing the ‘cancel’ button on the ‘VisitType’ view controller calls performOnDismissed so the child coordinator is removed.

Obviously, sometimes people just swipe down to dismiss the view controller. How do we remove the child coordinator in these cases?



@jrg.developer Can you please help with this when you get a chance? Thank you - much appreciated! :]

You’re right –– this does appear to be an issue… :scream:

As you hint at as well, iOS 13 changes the default way that view controllers are presented modally. They can now be dismissed by swiping down too. The ModalNavigationRouter doesn’t currently detect when this happens, so it doesn’t call performOnDismissed and nothing is cleaned up!

Fortunately, there’s an easy fix for this, by conforming to UIAdaptivePresentationControllerDelegate:

  1. Make ModalNavigationRouter conform to UIAdaptivePresentationControllerDelegate by adding the following to the end of ModalNavigationRouter.swift:
extension ModalNavigationRouter: UIAdaptivePresentationControllerDelegate {
  public func presentationControllerWillDismiss(_ presentationController: UIPresentationController) {
    performOnDismissed(for: presentationController.presentedViewController)
  1. Still within ModalNavigationRouter, add the following right before the closing curly brace within init(parentViewController: UIViewController):
navigationController.presentationController?.delegate = self

Check out the docs for UIAdaptivePresentationControllerDelegate for more information on what it does.

Here’s also another useful article about the modal presentation changes in iOS 13.

I’ll make sure the next edition of the book includes this fix too –– Thanks for pointing it out! :]