In iOS development, creating custom user experiences often involves presenting view controllers modally. While the default behavior allows users to interactively dismiss these presented view controllers with a swipe gesture, there are scenarios where you might want to disable the interactive dismissal of presented view controller. This could be to ensure the user completes a critical task, prevent accidental data loss, or guide them through a specific flow. Understanding how to control this behavior is crucial for building robust and user-friendly iOS applications. We’ll explore various methods to achieve this, providing clear examples and best practices to help you implement the solution effectively and avoid common pitfalls. We’ll also discuss why itโs important to consider user experience when disabling this feature.
Understanding Interactive Dismissal in iOS
Interactive dismissal, introduced with iOS 13, provides a natural and intuitive way for users to dismiss modal view controllers by simply swiping down. Itโs a user-friendly gesture that aligns with the platform’s design principles. However, in certain cases, such as when a user is filling out a form or viewing important information, allowing them to dismiss the view controller prematurely can lead to data loss or confusion. Therefore, developers often seek ways to programmatically control or disable the interactive dismissal of presented view controller to maintain control over the user flow and ensure a seamless experience. It’s essential to remember that disabling this feature should be done judiciously, as it can potentially frustrate users if not implemented thoughtfully. Always consider the user experience implications before making this change.
The isModalInPresentation property of a UIViewController is the key to controlling interactive dismissal. When set to true, it prevents the interactive dismissal gesture. This property is especially useful for scenarios where the presented view controller needs to enforce a specific action or prevent accidental closure. However, setting this property directly might not always be the most appropriate solution, especially if you need more fine-grained control. For example, you might want to temporarily disable the dismissal while a specific operation is in progress, then re-enable it afterward. We’ll cover these more advanced techniques later in this guide.
Apple’s Human Interface Guidelines emphasize the importance of respecting user expectations and providing consistent experiences. Disabling interactive dismissal should be a deliberate decision, not a default behavior. According to a study by Nielsen Norman Group, “Users are more likely to feel in control when they can freely navigate and dismiss views.” Therefore, ensure that the reason for disabling interactive dismissal is clearly communicated to the user, and provide alternative ways to dismiss the view controller, such as a “Save” or “Cancel” button. This can help mitigate any potential frustration and maintain a positive user experience.
Methods to Disable Interactive Dismissal
There are several ways to disable the interactive dismissal of presented view controller, each with its own advantages and disadvantages. The most straightforward method is to set the isModalInPresentation property of the presented view controller to true. This effectively disables the swipe-to-dismiss gesture and requires the user to interact with a button or other control to dismiss the view controller. This method works well for simple cases where you want to completely prevent interactive dismissal.
Here’s how to implement this in code:
let viewController = UIViewController() viewController.isModalInPresentation = true present(viewController, animated: true, completion: nil)
Another approach involves using a custom presentation controller. This allows for more granular control over the presentation and dismissal process. With a custom presentation controller, you can intercept the dismissal gesture and prevent it from occurring under certain conditions. This is particularly useful if you need to dynamically control the dismissal behavior based on the state of the view controller or the user’s actions. While this approach requires more code, it provides greater flexibility and customization options. Keep in mind that custom presentation controllers require a deeper understanding of UIKit’s presentation architecture.
For more advanced scenarios, you might consider using a delegate pattern. By implementing a delegate protocol in the presenting view controller, you can receive callbacks when the user attempts to dismiss the presented view controller. This allows you to perform validation checks or display confirmation alerts before allowing the dismissal to proceed. This approach provides a balance between control and user experience, as it allows you to prevent accidental dismissals while still giving the user the ultimate decision-making power. However, remember to avoid creating strong reference cycles between the presenting and presented view controllers when using delegates.
Best Practices and Considerations
When deciding to disable the interactive dismissal of presented view controller, itโs crucial to consider the user experience. Always provide alternative ways for the user to dismiss the view controller, such as a “Done,” “Cancel,” or “Save” button. This ensures that the user doesn’t feel trapped and can always exit the view controller when they’re ready. Avoid surprising the user by unexpectedly disabling the dismissal gesture without providing clear alternatives. A good rule of thumb is to always offer a clear and intuitive way for the user to regain control.
Consider these points when implementing this feature:
- Clearly communicate to the user why interactive dismissal is disabled.
- Provide alternative dismissal methods, such as buttons or other controls.
- Avoid disabling interactive dismissal unnecessarily.
Properly handle edge cases, such as when the user attempts to force-quit the app or receives a phone call. Ensure that your application state is saved appropriately so that no data is lost if the user is interrupted. Test your implementation thoroughly on different devices and iOS versions to ensure that it works as expected. Itโs also wise to conduct user testing to gather feedback on the user experience and identify any potential usability issues. Remember, the goal is to balance control with a positive user experience. According to a Microsoft study, “User frustration is a significant factor in app abandonment.”
Here’s a step-by-step guide to safely disabling interactive dismissal:
- Identify the view controllers where you need to disable interactive dismissal.
- Set the isModalInPresentation property to true in those view controllers.
- Provide alternative dismissal methods, such as buttons.
- Test your implementation thoroughly.
- Gather user feedback and iterate on your design.
Remember to document your code clearly and explain why you’ve chosen to disable interactive dismissal. This will make it easier for other developers (or yourself in the future) to understand your design decisions and maintain the code. Also, be mindful of accessibility considerations. Ensure that your alternative dismissal methods are accessible to users with disabilities, such as those who use assistive technologies like VoiceOver. By following these best practices, you can effectively disable the interactive dismissal of presented view controller while maintaining a positive and accessible user experience.
Advanced Techniques and Workarounds
For more complex scenarios, you might need to employ advanced techniques to disable the interactive dismissal of presented view controller conditionally. For example, you might want to disable it only when the user has unsaved changes or when a specific process is running. This requires a more dynamic approach that involves monitoring the state of the view controller and adjusting the dismissal behavior accordingly. One way to achieve this is by using a combination of KVO (Key-Value Observing) and custom logic.
You can observe changes to relevant properties, such as a flag indicating whether there are unsaved changes. When the value of this property changes, you can update the isModalInPresentation property accordingly. This allows you to dynamically enable or disable the interactive dismissal of presented view controller based on the current state of the application. However, be careful when using KVO, as it can be complex to manage and can lead to memory leaks if not implemented correctly. Always remember to unregister your observers when they’re no longer needed.
Another advanced technique involves using a custom UIPresentationController subclass. This allows you to intercept the presentation and dismissal process and modify the behavior as needed. For example, you can override the shouldDismissalTransitionBegin() method to prevent the dismissal from occurring under certain conditions. This approach provides a high degree of control but requires a deep understanding of the UIKit presentation architecture. Itโs also important to note that custom presentation controllers can be more complex to implement and maintain than simpler solutions. Learn more about advanced UI techniques here.
- **Q: Why would I want to disable interactive dismissal?**
- A: To prevent accidental data loss, ensure users complete critical tasks, or guide them through a specific flow.
- **Q: What is the easiest way to disable interactive dismissal?**
- A: Set the isModalInPresentation property of the presented view controller to true.
- **Q: What are the best practices for disabling interactive dismissal?**
- A: Provide alternative dismissal methods, communicate clearly to the user, and avoid disabling it unnecessarily.
- **Q: Can I disable interactive dismissal conditionally?**
- A: Yes, using techniques like KVO or custom presentation controllers.
- **Q: What iOS versions support interactive dismissal?**
- A: Interactive dismissal was introduced in iOS 13.
By utilizing isModalInPresentation, and other methods, you can ensure a smoother user flow within your app. Don’t forget that proper implementation involves not just the code, but also clear communication with the user. Provide undo options, save drafts automatically, and always ensure the user feels in control, even when you’re guiding them. Review Apple’s Human Interface Guidelines for detailed recommendations on modal view controllers. [External Link to Apple HIG](https://developer.apple.com/design/human-interface-guidelines/ios/views/modals/). Consider exploring related topics such as custom transitions and view controller containment to further enhance your iOS development skills. [External Link to Swift Documentation](https://www.swift.org/documentation/).
Controlling the dismissal behavior is just one piece of the puzzle. The ultimate goal is to create apps that are both functional and delightful to use. So, experiment with different techniques, gather user feedback, and continuously refine your approach to create the best possible user experience. You now have all the tools to effectively disable the interactive dismissal of presented view controller where appropriate, ensuring your applications remain intuitive and user-friendly. Don’t hesitate to dive deeper into these concepts and elevate your iOS development skills even further.
Question & Answer :
iOS 13 introduces a new design of modalPresentationStyle .pageSheet (and its sibling .formSheet) for modally presented view controllersโฆ
โฆand we can dismiss these sheets by sliding the presented view controller down (interactive dismissal). Although the new “pull-to-dismiss” feature is pretty useful, it may not always be desirable.
THE QUESTION: How can we turn the interactive dismissal off? - Bear in mind we keep the presentation style the same.
Option 1:
viewController.isModalInPresentation = true
(Disabled interactive .pageSheet dismissal acts like this.)
- Since the iOS 13,
UIViewControllercontains a new property calledisModalInPresentationwhich must be set totrueto prevent the interactive dismissal. - It basically ignores events outside the view controller’s bounds. Bear that in mind if you are using not only the automatic style but also presentation styles like
.popoveretc. - This property is
falseby default.
From the official docs: If
true, UIKit ignores events outside the view controller’s bounds and prevents the interactive dismissal of the view controller while it is onscreen.
Option 2:
func presentationControllerShouldDismiss(_ presentationController: UIPresentationController) -> Bool { return false }
- Since the iOS 13,
UIAdaptivePresentationControllerDelegatecontains a new method calledpresentationControllerShouldDismiss. - This method is called only if the presented view controller is not dismissed programmatically and its
isModalInPresentationproperty is set tofalse.
Tip: Don’t forget to assign
presentationController’s delegate. But be aware, it is known that even just accessing thepresentationControllercan cause a memory leak.

