dismissModalViewController AND pass data back
Master System Design with Codemia
Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.
Introduction
Passing data back while dismissing a modal view controller is a standard iOS workflow for forms and pickers. Older code used dismissModalViewControllerAnimated, but modern UIKit uses dismissViewControllerAnimated:completion:. The important part is not dismissal itself, it is choosing a clear channel for returning values to the presenting controller.
Modern Dismissal Pattern In UIKit
If the presented controller needs to return one value, a delegate is usually the most explicit pattern in Objective C. The child view controller informs the parent through a protocol method, and the parent decides what to do with the result.
The parent sets itself as delegate before presenting.
Parent Controller Integration
This avoids global notifications and keeps ownership explicit.
When To Use Completion Blocks Or Notifications
For one off interactions, a completion block property is lightweight and easy to follow. For app wide events, notification center can work, but it is less explicit and harder to refactor safely.
A practical rule:
- Delegate for structured one to one communication.
- Completion block for simple callback payloads.
- Notification center only for broad broadcast style events.
Also ensure dismissal happens on the main thread. UIKit updates are not thread safe, and background thread dismissal can cause inconsistent transitions.
Migration Note For Legacy APIs
If you maintain older code, replace dismissModalViewControllerAnimated with dismissViewControllerAnimated:completion:. The old API is deprecated and should not be used in modern iOS targets. Migration is usually mechanical, but review data flow at the same time so you do not carry forward brittle patterns.
Testing And Reliability Checklist
Modal flows should be covered by UI tests because timing issues are easy to miss in manual checks. Validate the full round trip: present modal, enter value, save, dismiss, and assert the parent state changed. Add a cancel path test as well so dismiss without save does not overwrite existing data.
Memory behavior matters too. If you choose block callbacks, confirm the modal does not retain the parent strongly. A weak capture for controller references is often required to avoid leaks. Instruments can verify deallocation after dismissal.
Finally, keep transition and data code separate. The modal should emit a result through one channel, and the parent should own persistence and UI refresh. This separation improves reuse and makes failures easier to isolate during debugging.
A small naming convention also helps: use didSave, didCancel, and didDelete style delegate methods so callback intent is obvious during reviews.
Common Pitfalls
- Dismissing before sending data back, causing the parent to miss updates.
- Using strong references in callbacks and creating retain cycles.
- Relying on notification center for local one screen interactions.
- Updating presenting controller UI before data state is actually changed.
- Mixing several return channels in one flow, which makes behavior unpredictable.
Summary
- Use modern UIKit dismissal APIs for modal flows.
- Return data with delegates for clear controller boundaries.
- Keep data handoff explicit before or during dismissal.
- Prefer one communication pattern per interaction.
- Audit legacy modal code for deprecated API usage and weak ownership bugs.

