Xamarin.forms: iOS 13 Modal Compatibility updates

Created on 13 Aug 2019  ·  35Comments  ·  Source: xamarin/Xamarin.Forms

Current iOS 13 Modal State

iOS13 changes the default modalPresentationStyle from FullScreen to PageSheet. This means if modalPresentationStyle on a UIViewController is set to Automatic (which it is on Forms) then it will display as PageSheet on iOS13 and FullScreen on anything earlier

  • Page Sheet means that users can swipe away Modal Dialogs
  • Page Sheet causes different life cycle behavior to occur on the UIViewController that's being covered so currently if you swipe away Page Sheet it will cause all Modal behavior to break

  • Anyone running Forms apps on iOS13 will currently be met with a broken experience if users swipe away Modal dialogs. When ModalBehavior on iOS13 is set to automatic (which it currently is) then it will use PageSheet by default. When Page Sheet is swiped away it won't fire the Appearing/Disappearing events for the Page covered by the Modal.

Changes we should apply to 3.6+ (this doesn't guarantee we will release an SR for all 3.6+ versions)

https://github.com/xamarin/Xamarin.Forms/pull/6558 already has some of these changes implemented

  • Fix OnAppearing/OnDisappearing events if we determine the modalPresentationStyle that will display is not FullScreen

    • Basically if modalPresentationStyle is Automatic on versions below iOS13 then use existing LifeCycle code. Otherwise use the new code that's in #6558

    • Disable the ability to swipe away a PageSheet modal dialog if the modalPresentationStyle is set to Automatic. If the developer has set the modalPresentationStyle themselves to PageSheet then we'll just let swipe to dismiss work and it's up to the developer to deal with.

  • Provide documentation of how to create a PageRenderer that's able to disable swipe away behavior and/or change the modalPresentationStyle. This way developers who are on older versions of Forms will know how they can work around the issue until they are able to upgrade to a newer version

iOS FormSheet and PageSheet comparisons

  • On iOS 13 iPad Page Sheet will size itself based on the dynamic text size of a font so it's more accessible. With larger text the Modal window will be larger. We currently have a platform specific for setting the modal style to FormSheet but we should add PageSheet and PageSheet should be the preferred behavior to use (https://github.com/xamarin/Xamarin.Forms/pull/6558)

iPad running iOS 13

Page Sheet with Large Text On
image

Page Sheet with Large Text Off
image

Form Sheet with Large Text Off
image (1)

Form Sheet with Large Text On
image

modal high iOS 13 high impact iOS 🍎 proposal-accepted enhancement ➕

Most helpful comment

Oh man I'm a happy camper right now. Downgrading fixed all our issues.

Here's what I did:

All 35 comments

Is there a way to force current applications to use UIViewController FullScreen instead of Automatic? The lifecycle behavior is breaking our app at the moment and most of the modals may not be dismissed.

Pushmodalaysnc fails on our App in IOS13. We are on Xamarin 3.6. Is there a patch in progress? By when will it be released? Our app is not working properly with IOS13. Thanks.

We have huge problems with after swipe closing modal, modal pages are still on stack (non visible´?) or something, preventing us from pushing more modals and makes our app unresponsive.
When can this be fixed? xamarin forms 3.6

I think Xamarin Forms developers shouldn't have updated to the new VS for Mac and XCode 11. Apps build via XCode 10 will work as expected on iOS13 because of backwards compatibility. The apps build with XCode 11 will break.

Updating VS for Mac will force an XCode update, just leave it be for now.

I will try to downgrade to VS for Mac 8.2 and XCode 10 and will report if this fixed my issues.

Oh man I'm a happy camper right now. Downgrading fixed all our issues.

Here's what I did:

Update: Found workaround by upgrading Xamarin.Forms to a later build, which prevented slide-to-close on modals, which solved our issue.
Visual studio 16.3
Visual studio for mac: 8.3
Xcode: 11
Xamarin.Forms 3.6.0.709228

Ran into this issue while testing our app after upgrading to XCode 11 and testing on an iPad running 13.1.1. Upgrading to Forms 3.6.0.709228 and also setting the ModalPresentation style for the navigation page fixed all the modal pushes appearing as a sheet.

<NavigationPage 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    BarBackgroundColor="{StaticResource pageBackgroundColor}"
    xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific.AppCompat;assembly=Xamarin.Forms.Core"
    xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
    ios:NavigationPage.IsNavigationBarTranslucent="true"
    ios:NavigationPage.HideNavigationBarSeparator="true"
    ios:Page.ModalPresentationStyle="FullScreen"
    x:Class="Foobar.Views.AppNavigationPage">
</NavigationPage>

Ran into this issue while testing our app after upgrading to XCode 11 and testing on an iPad running 13.1.1. Upgrading to Forms 3.6.0.709228 and also setting the ModalPresentation style for the navigation page fixed all the modal pushes appearing as a sheet.

<NavigationPage 
    xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
    BarBackgroundColor="{StaticResource pageBackgroundColor}"
    xmlns:android="clr-namespace:Xamarin.Forms.PlatformConfiguration.AndroidSpecific.AppCompat;assembly=Xamarin.Forms.Core"
    xmlns:ios="clr-namespace:Xamarin.Forms.PlatformConfiguration.iOSSpecific;assembly=Xamarin.Forms.Core"
    ios:NavigationPage.IsNavigationBarTranslucent="true"
    ios:NavigationPage.HideNavigationBarSeparator="true"
    ios:Page.ModalPresentationStyle="FullScreen"
    x:Class="Foobar.Views.AppNavigationPage">
</NavigationPage>

I am not seeing this Platform Specific "ios:Page.ModalPresentationStyle="FullScreen". Using XF 3.6.0.709228 or even the latest 4.2. What am i missing!?

Usually don't appear in intelisense, resharper etc but for iPad devices it works as described. My current project unusually doesn't have phone support, just tablet.

Test it and see if it works.

@mackayn @troabrea @GuidoNeele

  • Anyone that can attach a repro targeting the latest 3.6 with modal not showing as full screen would be helpful

  • Anyone that can't update past 3.6 letting us know why would also be helpful :-)

As time goes on fewer and fewer iOS13 related fixes will make it to 3.6

Any news on this? I don't want to downgrade Xcode and Visual studio for this issue in iOS13.. Is there any alternative?

@emiliobongiorno can you expand on why you need to downgrade?

3.6+ versions should all work fine on ios13

Maybe I am miss-understanding something after reading the comments here, and there is a chance that my problem is not related to this.

I downgraded to 3.6+ but I am still having this issue:
When showing "Interstitial ads" of Admob, they are shown as modals (this new 'popups' of iOS 13), and I want to show them on full screen as before.
I used this implementation for iOS Intesrtitials (look for AdInterstitial_iOS class)
I already tried to do something like this but still showing as popups on iOS13:
viewController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;

Any idea what I am missing?

Thanks in advance

@emiliobongiorno that's going to be something that's more related to to the Admob library and not Xamarin forms

The API that displays the popup https://developers.google.com/admob/ios/api/reference/Classes/GADInterstitial#-presentfromrootviewcontroller: isn't under our control

This Issue reflects Modal windows that are created from our cross platform code.

Any other library that presents Modals with its own code will need to be updated to work with iOS 13

I see.. Thanks @PureWeen !
I already open an issue here
Regards!

Maybe I am miss-understanding something after reading the comments here, and there is a chance that my problem is not related to this.

I downgraded to 3.6+ but I am still having this issue:
When showing "Interstitial ads" of Admob, they are shown as modals (this new 'popups' of iOS 13), and I want to show them on full screen as before.
I used this implementation for iOS Intesrtitials (look for AdInterstitial_iOS class)
I already tried to do something like this but still showing as popups on iOS13:
viewController.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;

Any idea what I am missing?

Thanks in advance

I'll clarify why I downgraded VS for Mac and XCode. I was under time pressure to fix a bug and I couldn't spend the time to test our app compiled against the new bits. I hadn't realised what effect updating to 8.3 would make to the app and the way it works. I tried adding the platform specific to our NavigationPage before downgrading, but it didn't fix it for me, I kept getting a PageSheet. So not finding any answers to the problems I had forced me to downgrade, also because this was the less time consuming and safe thing to do. BTW We are on Xamarin Forms 4.1.

If anyone can send me a repro of getting PageSheet with iOS 13 on the latest patch/pre release of any XF version 3.6+ I will create a PR and fix it

Has anyone solved the FullScreen problem using a custom renderer? Any guidance on how to do that? I have a client on XF 3.1 and I need to get out a build for iOS 13 before I can stop to take the time to upgrade XF and all of their other dependencies.

@jawbrey

  • Create a Custom Page Renderer
  • When it's added to the parent controller set the ModalPresentationStyle on that parent to full Screen

I think that should work

https://github.com/xamarin/Xamarin.Forms/blob/f17fac7b9e2225b1bfe9e94909d2b954106f8f1f/Xamarin.Forms.Platform.iOS/ModalWrapper.cs#L18

We have the same problem in a Forms 2.5 application.

I tried the approach with a custom page renderer:

[assembly: ExportRenderer(typeof(ModalPage), typeof(ModalPageRenderer))]
namespace My.iOS.Custom.Components.Pages
{
    public class ModalPageRenderer : PageRenderer
    {
        public override void WillMoveToParentViewController(UIViewController parent)
        {
            parent.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
            base.WillMoveToParentViewController(parent);
        }
    }
}

I can verify that the property was correctly set on the parent, but it does not have any effect.

@bnoffer not sure why you are seeing that

I've attached a 2.5 project and for me it shows up as Full Screen using your above code
App154.zip

@PureWeen thanks, that does work for me. I was missing the need to overrride WillMoveToParentViewController

@PureWeen thanks for verifying.

I found the reason why it was not working. we have another page renderer in the application that was basically overriding the change.

My final addition to the renderer looks like this:

public override void WillMoveToParentViewController(UIViewController parent)
{
    if (parent != null) parent.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
    base.WillMoveToParentViewController(parent);
}

I'm having this issue in iPhone, and none of the solitions works for me.

Hi @rayita ,
a bit more information would be helpful. If you tried the PageRenderer fix make sure that you have no other competing PageRenderers associated to the pages where you want to apply the fix. If you do not have any other PageRenderer you can try to connect the Renderer to the Xamarin.Forms Page class, then those settings will be applied to all Pages. That is how it is now done in our application on Xamarin.Forms 2.5 and it is working fine.

Hi @rayita ,
a bit more information would be helpful. If you tried the PageRenderer fix make sure that you have no other competing PageRenderers associated to the pages where you want to apply the fix. If you do not have any other PageRenderer you can try to connect the Renderer to the Xamarin.Forms Page class, then those settings will be applied to all Pages. That is how it is now done in our application on Xamarin.Forms 2.5 and it is working fine.

We have several apps, some using Xamarin.Forms 3.6, and others using Xamarin.Foms 4, all of them show modals in PageSheet format in iPhones (with all the problems related because if user swipe down the modal this is not removed from navigation stack).

We try both propoused solutions: ios:Page.ModalPresentationStyle="FullScreen" and custom page renderer with parent.ModalPresentationStyle = UIModalPresentationStyle.FullScreen; in WillMoveToParentViewController.

None of the works.

May be the problem is XF 3 and XF 4, in this case it would be XF bug.

@rayita find the attached sample project. A project using XF 3.6 and showing a fullscreen modal just as before, also on iOS 13. Does this help you make the code changes you need?

Also see: https://docs.microsoft.com/xamarin/xamarin-forms/platform/ios/page-presentation-style

ModalFullScreen.zip

Check this out, a fix for presentation swipe to close (doesn't fix OnAppearing/OnDisappearing events)
https://github.com/MvvmCross/MvvmCross/issues/3546#issuecomment-537940587

@rayita find the attached sample project. A project using XF 3.6 and showing a fullscreen modal just as before, also on iOS 13. Does this help you make the code changes you need?

Also see: https://docs.microsoft.com/xamarin/xamarin-forms/platform/ios/page-presentation-style

ModalFullScreen.zip

@jfversluis Thank you very much.

We try this and did not work, but finally we realize the problem!
We where using XF 3.6.0.344457 and " ios:Page.ModalPresentationStyle" property did nothing, we update to XF 3.6.0.709228 and now all works fine.

We check also laste XF 4 version and all works fine too (by default with need to change any property).

Unfortunately, any of the 709 releases, like 3.6.0.709228 is no good as it has a huge iOS bug with ContextActions. #8243

I found a simple workaround for my MvxTableViewController. I would assume this will resolve it for any type of view controller.

In the viewcontroller's ViewDidLoad, add the ModalInPresentation = true. See below

Class def:

[MvxModalPresentation(
    ModalPresentationStyle = UIModalPresentationStyle.PageSheet, 
    WrapInNavigationController = true)]
public partial class MyTableView : MvxTableViewController<...>

{
...
public override void ViewDidLoad()
{
base.ViewDidLoad();
ModalInPresentation = true;
...
}

}

We have the same problem in a Forms 2.5 application.

I tried the approach with a custom page renderer:

[assembly: ExportRenderer(typeof(ModalPage), typeof(ModalPageRenderer))]
namespace My.iOS.Custom.Components.Pages
{
    public class ModalPageRenderer : PageRenderer
    {
        public override void WillMoveToParentViewController(UIViewController parent)
        {
            parent.ModalPresentationStyle = UIModalPresentationStyle.FullScreen;
            base.WillMoveToParentViewController(parent);
        }
    }
}

I can verify that the property was correctly set on the parent, but it does not have any effect.

it works perfectly as expected

I tried with a couple of recent version of XF and ios:Page.ModalPresentationStyle isn't recognized and doesn't work. I am using VS for Mac 8.4.2 (build 59) and I have Xcode Version 11.3.1 (11C504). I even tried on of the 3.6 builds but no luck. Only the custom page renderer solution seems to work.

I found a simple workaround for my MvxTableViewController. I would assume this will resolve it for any type of view controller.

In the viewcontroller's ViewDidLoad, add the ModalInPresentation = true. See below

Class def:

[MvxModalPresentation(
    ModalPresentationStyle = UIModalPresentationStyle.PageSheet, 
    WrapInNavigationController = true)]
public partial class MyTableView : MvxTableViewController<...>

{
...
public override void ViewDidLoad()
{
base.ViewDidLoad();
ModalInPresentation = true;
...
}

}

I have tried this in both my NavigationRenderer and my PageRenderer and it doesn't seem to work for me. I'm trying to prevent the swipe to dismiss behavior when the page is presented as a FormSheet.

Was this page helpful?
0 / 5 - 0 ratings