You hear about the large features in new major version iOS updates, but it’s often the small changes that cause you headaches: the places where Apple has deprecated functionality or changed defaults that you’ve been relying on for years.
iOS 13 has one of those major changes with respect to how modal ViewControllers are displayed. They are now displayed in a card format by default. That itself is not overly problematic, but as part of that change, it also enables the user to dismiss a modal by swiping down from the top of the screen.
If your app expects that it will have full control over being dismissed, this could be a major problem. Suddenly, your login form that you are displaying with a modal can just be swiped away, leading to unexpected behavior: crashes, unpopulated screens, access to things a user shouldn’t have access to.
Building with the old iOS 12 SDK is an option — for a while. How do you restore that classic functionality, making your modals fullscreen by default, with full control over how they are dismissed? Thankfully, it is not a hard fix, but the fix depends on how you are presenting your ViewController. Let’s cover all of the different fixes now.
Presenting ViewController fully programmatically
If you are constructing your ViewController and presenting it all in code, add this single line after constructing your ViewController:
vc.modalPresentationStyle = .fullScreen
modalPresentationStyle should be set on the ViewController that is being presented. For example, if you are wrapping your ViewController in another VC, like a NavigationController, you should set the style on the NavigationController.
Presenting via a storyboard segue
If you are presenting your ViewController via a storyboard segue, setting this checkbox on your segue will make your modal present in the classic way:
Presenting by retrieving a VC from a storyboard or XIB, then presenting programmatically
If you are retrieving a ViewController from a storyboard or XIB, then presenting programmatically, you can either use the code from the fully programmatic case above, or you can set this checkbox on your ViewController in Interface Builder: