Controlling iOS 13 modal presentation styles in Xamarin.Forms
With the official release of iOS 13, I’ve found that as I move some of the apps I work on up to targeting this that various UI components don’t work as they used to. So far, this isn’t nearly as much of an issue as the transition from iOS 6 to iOS 7 (for those who remember) however it has come with its own hiccups here and there.
I’ve been using modal screens in apps for a long time now, very often for one simple purpose: it forces a user to make a decision. This is especially relevant when dealing with things like records being edited and either saving or abandoning changes.
To save the headache of tying into all the possible ways of navigating back from within a navigation stack, displaying a screen as modal has been a great way to solve this and not worry about the differences between Android physical buttons vs virtual (again, for those who remember) and new gestures like when Apple introduced the swipe from left to right to navigate back.
Now it seems, with Apple changing gestures that this has broken the paradigm again by displaying modals as sheets that the user can swipe away without any warning about losing potentially unsaved data.
This fundamentally broke a few apps that I ran up on iOS 13. Apple fortunately however has provided a way to explicitly display modals in full screen, the way they previously were, and the Xamarin.Forms team did a great job addressing this.
You can set the modal presentation style in XAML or C# to set this to what you want the modal behaviour to be like. This this is a very nice and clean approach:
For several of my projects however, this wasn’t an option because they were on older versions of Xamarin.Forms that not all clients would would update for various reasons.
Another issue I faced on projects that I did update Xamarin.Forms for, was that (at the time of writing this) the awesome MVVM framework I use for some projects, Michael Ridland’s FreshMvvm for Xamarin.Forms, references Xamarin.Forms 18.104.22.1689999 that takes the iOS 13 default behaviour and displays modals using the over fullscreen sheet approach, which breaks screens that are intended to force the user to make a choice because they can simply swipe it away.
Thankfully, without too much effort, there is a solution that enables you to choose your modal presentation style with older Xamarin.Forms versions.
To get around this, in the end going back to the good old tried and true custom renderer approach and setting the presentation style in WillMoveToParentViewController for the NavigationRenderer does the trick:
It’s not as elegant as the official Xamarin.Forms way, but this should hopefully work if like me you find issues or you’re on older versions of Xamarin.Forms through third-party libraries or have clients who don’t want to upgrade because of test footprint or whatever reason.
This was driving me mad for a couple of hours with some projects so hopefully this helps save some headaches if you find yourself in a similar situation.
Also if you want to play around with the different modal presentation styles using either approach, the different types are defined in this enum for Xamarin.Forms:
As usual, if you want the entire working example, please have a look here on GitHub.
Edit 20 Oct 2019: As pointed out by Gerald Versluis below, if you do want to use the sheet display in iOS 13+ and not the above full screen mode that was the default, there is, at time of writing this, an issue in Xamarin.Forms where the swipe down to dismiss is not detected on iOS 13+ and thus the modal stack becomes out of sync and further calls to PushModalAsync() won’t work. To get around this, you can use the following code in the modal pages to ensure the stack integrity is maintained.
Also worth noting that from the comments in the GitHub issue that Gerald has flagged below that he has a draft fix ready so hopefully this will be in a version of Xamarin.Forms soon so that people who are in a position to update and not held back due to the reasons mentioned above, will be able to use both approaches easily with the latest Xamarin.Forms soon :).
Matt has been developing software for over 17 years and these days specialises in cross-platform app development. He's developed dozens of apps on several of the app stores including apps hitting #1.
Matt's worked for large software companies, enterprise size organisations, the Australian government as well as various startups on cutting edge technology.
Originally from New Zealand, Matt currently lives in Brisbane with his wife and a Jack Russell and Westie.