Modality changes in iOS13

iOS

One behavior that changed and might break your old app once you starting adopting new iOS 13 is the modal presentation.

What changes?

So with iOS 13, default presentation for modal is now in sheet style.

Modal View

It is beautiful and packs with useful gestures.

Swiping down from the top of the screen
Swiping down from anywhere on the screen when card content is scrolled to the top
With great gestures come great responsibility, these new gestures mean users can dismiss the modal anytime they want with a swipe down gesture which might not be the behavior you want.

Insist on the old design

You can say no to this design and stay with good the old full-screen presentation style by setting modalPresentationStyle to .fullScreen

vc.modalPresentationStyle = .fullScreen
present(vc, animated: true, completion: nil)

Or set presentation style under the Attributes Inspector.

Set full screen modal in Storyboard

Embrace the changes

This is the right way to go, but there would be a time where we want to prevent users to swipe our modal to dismiss it. Apple provided us 2 ways to handle this.

A simple way

If you just want to simply prevent users from dismissing the modal just set isModalInPresentation to true in a modal view controller. This flag prevents swipe to dismiss gestures when users try to dismiss it will show a beautiful bounce back animation.

modal bounce

Advance

If you want to get notified and response according to this dismissal interaction you can do that too. Apple added 4 new instance methods under UIAdaptivePresentationControllerDelegate just for this.

Instance methods

UIAdaptivePresentationControllerDelegate is a property in UIPresentationController, you have to assign a modal view controller as a delegate first. Set it like this in prepare(for segue: UIStoryboardSegue, sender: Any?)

override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
// Get the presented navigationController and the view controller it contains
let navigationController = segue.destination as! UINavigationController
let modalViewController = navigationController.topViewController

// Set the modal view controller to be the delegate of the presentationController for this presentation,
// so that modal view controller can respond to attempted dismissals
navigationController.presentationController?.delegate = modalViewController
}

After setting our view controller to be the delegate of the presentationController, we can start responding to these methods.

Can't dismiss scenario
If isModalInPresentation is true and users try to dismiss, presentationControllerDidAttemptToDismiss(_:) will be called.

if isModalInPresentation is false, the thing gets a little bit complicated.

First presentationControllerShouldDismiss(_:) will be called, if it is false, presentationControllerDidAttemptToDismiss(_:) will be called.

Dismissable scenario

if isModalInPresentation is false and presentationControllerShouldDismiss(_:) return true, presentationControllerWillDismiss(_:) will get called and once a modal is dismissed presentationControllerDidDismiss(_:) will be called.

One thing to consider here is presentationControllerWillDismiss(_:) can be called many time as users drag their finger up and down, so be thoughtful about what logic you would put there.

It is quite complicated, so this flow from Modernizing Your UI for iOS 13 session sum it up nicely.

dismissal life cycle

Even though it looks complicated, in most case what you need to do is set isModalInPresentation to true whenever you see fit and response to presentationControllerDidAttemptToDismiss(_:).

dismiss interaction

This example set isModalInPresentation to true if the edited text is not the same and in presentationControllerDidAttemptToDismiss(_:) we present UIAlertController asking for user's intention whether he/she mean to save or discard the changes and act accordingly.

Conclusion

This is welcoming change for me since iOS devices getting bigger and bigger, reaching your finger to the top to tap cancel/close button is no longer an easy task, having this gesture out of the box would help on this problem.

Apple provided some guidance about the use case for both fullscreen and sheet I encourage you to check it out and judge for yourself which style would suit your app.

References


← Home