dismissModalViewControllerAnimated deprecated
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
dismissModalViewControllerAnimated: was part of the older UIKit modal presentation API. Apple deprecated it in favor of dismissViewControllerAnimated:completion:, which fits the modern view controller presentation model and supports completion callbacks.
If you still see the deprecated call in legacy Objective-C code, the fix is straightforward. The important part is understanding which controller should dismiss the presentation and when the completion block runs.
What Replaced the Deprecated API
Older iOS code often looked like this:
The modern replacement is:
The newer method works for modal presentations created with presentViewController:animated:completion: and gives you a completion block for cleanup, state updates, or chained navigation.
Here is a basic presentation and dismissal flow in Objective-C:
That is the direct replacement most projects need.
Who Should Call Dismiss
In UIKit, the presenting controller manages the modal relationship, but the presented controller can still ask UIKit to dismiss itself. In practice, both of the following are common and valid:
- The presented controller calls
[self dismissViewControllerAnimated:YES completion:nil]; - The presenting controller calls
[self.presentedViewController dismissViewControllerAnimated:YES completion:nil];
The first option is often simpler inside a modal screen's cancel or done action:
If your modal is embedded in a navigation controller, dismiss the modal container rather than trying to pop it off the navigation stack. Modal dismissal and navigation popping are different operations.
Why Apple Deprecated the Old Method
The deprecation reflects a broader UIKit cleanup. Apple moved from a specialized modal API toward a more consistent view controller presentation system. The newer methods:
- match
presentViewController:animated:completion: - support completion blocks
- work better with custom transitions
- fit newer presentation styles such as form sheets and page sheets
That consistency matters when an app grows beyond a single full-screen modal flow.
Modal Dismissal Versus Navigation
Legacy projects often mix modal presentation with navigation-controller pushes, which is where confusion starts. A modal controller should be dismissed. A pushed controller should be popped.
If you use the wrong operation, UIKit may do nothing or remove the wrong screen. Before changing old code, verify whether the screen was shown with presentViewController or pushed with pushViewController.
Migrating Legacy Code Safely
For most projects, migration is a text-level API update plus a quick check of the call site. Replace the deprecated call, then verify that the controller being dismissed is actually the one presented modally.
A common legacy pattern looks like this:
After migration:
If cleanup logic depends on the dismissal finishing, move that logic into the completion block:
That is more reliable than running the cleanup immediately before the animation completes.
Swift Equivalent
Many mixed iOS codebases use both Objective-C and Swift. The Swift call is nearly identical:
If you are modernizing an older project, it helps to remember that the API concept stayed the same even though the syntax became shorter.
Common Pitfalls
One common mistake is dismissing the wrong controller. If a modal screen contains a navigation controller, dismiss the presented navigation controller instead of trying to pop the visible child controller.
Another issue is confusing modal dismissal with stack navigation. dismissViewControllerAnimated:completion: closes a modal presentation. popViewControllerAnimated: removes a controller from a navigation stack. They solve different problems.
Developers also sometimes ignore the completion block and trigger follow-up UI too early. If the next action depends on the modal being gone, put that work in the completion handler.
Finally, do not keep deprecated calls around for backward compatibility unless you truly support very old iOS targets. For any modern project, the replacement API is the correct default.
Summary
- '
dismissModalViewControllerAnimated:is deprecated and should be replaced.' - Use
dismissViewControllerAnimated:completion:for modern UIKit modal dismissal. - The presented controller can usually dismiss itself with the new API.
- Use the completion block for cleanup or follow-up navigation.
- Be careful not to confuse modal dismissal with navigation controller popping.

