iOS Lifecycle When Dismissing a Modal View With .pageSheet in iOS 13
Two key points in the behavior of the new modal view when it is dismissed
Since iOS 13, you have been able to implement a half-modal behavior as a screen transition by default and close the modal view by swiping down.
New Instance Methods of
The Lifecycle When Dismissing a Modal View With .pageSheet by Swiping
When you use the delegate methods, you have to get your head around the lifecycle when dismissing a modal view. It is easy for you to understand it by looking at some WWDC19 slides.
falseor not configured, the following methods are called in this sequence order:
What is isModalPresentation?
isModalPresentation is a new
UIViewController property from iOS 13.
If the property is
true, the view, which is displayed onscreen modally, is prevented from being dismissed. In other words, the modal view cannot be closed by swiping down when the property is
In this case, using
DidAttemptToDismiss is beneficial. It is a delegate method called by the event that fires when swiping down and
Therefore, you can run
dismiss(animate: true), processing things such as showing a dialog or something like that in the delegate method at your convenience.
“The default value of this property is false. When you set it to true, UIKit ignores events outside the view controller’s bounds and prevents the interactive dismissal of the view controller while it is onscreen.” — Apple Developer Documentation
Two Control Patterns When Swiping Down a Modal View With .pageSheet
viewWillAppear is never called on the parent view controller when swiping down a modal view with
.pageSheet, you have to use the aforementioned delegate methods when you want to pass values, events, and so on to the parent view controller.
Below are two general patterns of the implementation.
Pattern 1: No controlling the behavior when dismissing a modal view with .pageSheet
When you set false or nothing to
.isModalPresentation, as the delegate methods
DidDismiss can be called, you can pass events by delegate or closure methods by using
Adding: I noticed one issue with the above implementation. The delegate methods are called after the modal view is closed completely, therefore, a little delay could occur depending on the latter processing.
If so, you are better off calling
DidAttemptToDismiss and passing events through delegate methods or closures, as the performance is slightly faster (about 0.5 sec).
Pattern 2: Controlling the behavior when dismissing a modal view with .pageSheet (cited from Apple sample code)
The Apple sample code sets
isModalPresentation to true and uses
How does it work?
- If you edit text in the modal view and then swipe down, the app shows a dialog to confirm if you want to save or discard the changes.
- The app runs
dismiss(animated: true)when you select an action in the dialog. Passing values and propagating events to the parent view controller also occur at the same time.
You have to grasp the following key points in the behavior of the new modal view when being dismissed.
- The lifecycle changes significantly depending on
viewWillAppearis never called on the parent view controller when dismissing a modal view.