Detecting sheet was dismissed on iOS 13
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
On iOS 13, modal presentations changed because many view controllers are shown as sheets by default instead of full-screen. That means users can dismiss them with a swipe, and code that relied only on button taps or viewDidDisappear often stopped being precise enough. The correct way to detect sheet dismissal is usually through UIAdaptivePresentationControllerDelegate.
Why iOS 13 sheets behave differently
Before iOS 13, many apps presented modals full-screen and controlled dismissal more tightly. With sheet-style presentation, the system can dismiss the modal interactively. That creates a new question: how do you know the sheet was actually dismissed, not just partially dragged or requested for dismissal.
Apple added delegate callbacks on the presentation controller for exactly this reason.
Set the presentation controller delegate
The first step is assigning a delegate to the presented view controller's presentationController.
presentationControllerDidDismiss is the key callback when the dismissal has actually completed. That is usually the method you want if the goal is "run logic after the sheet is gone."
Other useful dismissal callbacks
Depending on the behavior you need, other delegate methods matter too.
These callbacks let you distinguish between:
- An attempted dismissal
- A permitted dismissal
- A completed dismissal
That is much more precise than trying to infer user intent from general lifecycle methods.
Prevent dismissal when needed
If the sheet contains unsaved data, you may want to block swipe dismissal temporarily.
isModalInPresentation = true tells the system not to dismiss the sheet interactively. Then presentationControllerDidAttemptToDismiss becomes useful for showing a confirmation dialog.
Why viewDidDisappear is not enough
Developers sometimes use viewDidDisappear to detect sheet dismissal. That can work in some cases, but it is broader than sheet dismissal and can fire for other reasons, such as view hierarchy changes or navigation transitions.
If your question is specifically about iOS 13 sheet dismissal, the presentation-controller delegate is more accurate and easier to reason about.
Common Pitfalls
The most common mistake is forgetting to set presentationController?.delegate. If the delegate is never assigned, the callbacks never fire.
Another issue is expecting these methods to behave the same for every modal style. If the controller is presented full-screen instead of as a sheet, the interaction model is different.
Developers also overuse viewDidDisappear for dismissal detection when they actually need sheet-specific intent and timing.
Finally, be careful about where you assign the delegate. It should be set on the presented controller's presentation controller early enough that the dismissal callbacks are available when the user interacts with the sheet.
If your sheet is embedded inside a navigation controller, double-check which controller actually owns the presentation controller. The delegate must be attached to the presented container that the system is dismissing.
Summary
- On iOS 13, sheet-style modals should usually be observed through
UIAdaptivePresentationControllerDelegate. - Use
presentationControllerDidDismissto detect completed dismissal. - Use
presentationControllerWillDismiss,ShouldDismiss, andDidAttemptToDismissfor finer control. - Set
isModalInPresentationwhen you need to block interactive dismissal. - Prefer presentation-controller callbacks over generic lifecycle methods for sheet-specific logic.

