rotorgames / Rg.Plugins.Popup

Xamarin Forms popup plugin
MIT License
1.15k stars 337 forks source link

iOS Alerts are rendered BEHIND popup, should always be infront. How can be change the z axis of the popup? (Android is fine) #671

Open innomotionmedia opened 3 years ago

innomotionmedia commented 3 years ago

If on iOS (Xamarin.Forms) requests an alert ( like a toast on android ), the alert is rendered BEHIND the popup, while alerts SHOULD OFC ALWAYS be in front. How can we make that happen?

Platforms affected (mark all that apply)

LuckyDucko commented 3 years ago

@innomotionmedia

Can you provide a sample project, with the alerts that you are using (DisplayAlert, or 3rd Party)

innomotionmedia commented 3 years ago

@LuckyDucko Sure. I am simply using the standart iOS Alert as a custom component in a xamarin.forms application (called in PCL):

    void ShowAlert(string message, double seconds)
    {
        alertDelay = NSTimer.CreateScheduledTimer(seconds, (obj) =>
        {
            dismissMessage();
        });
        alert = UIAlertController.Create("Ein Hinweis:", message, UIAlertControllerStyle.Alert);
        var window = UIApplication.SharedApplication.Delegate.GetWindow();
        window.RootViewController.PresentViewController(alert, true, null);

    }

If the popups are open and in within this popup this ShowAlert() func is called, the alert (toast) will be rendered behind the popup. If I move the popup out of view (very high for instance) and the message is rendered at the bottom, I can see the message, but the message is then also "darkend" as it is part of the page behind (which is all darkend).

I worked around this issue by using await DisplayAlert() on IOS in PCL. This standart iOS Alert (with buttons) is rendered infront of your popup, but it would be nice to have this "toast" kinda message also working on iOS ontop of the popups :)

beeradmoore commented 3 years ago

While I don't have a sample to share, we recently come across another example we discovered and fixed a few days ago. We are displaying a PopupPage as sort of a bottom menu allowing the user to hit share and then the native share dialog appears. After the share dialog is finished, we dismiss the Popup page.

In our case we found that when you go to this ContentPage, everything is in correct order. However, when you push+pop modal (another ContentPage) from this page, then display PopupPage, and then the share dialog it will be behind the PopupPage.

I didn't think much of it at the time because I just changed the dismiss of the PopupPage to be before we present the share dialog. But I do wonder if this is realated.

LuckyDucko commented 3 years ago

In our case we found that when you go to this ContentPage, everything is in correct order. However, when you push+pop modal (another ContentPage) from this page, then display PopupPage, and then the share dialog it will be behind the PopupPage.

@beeradmoore I have read this 4-5 times and I still am not understanding what is going on hahaha. can you edit this to have like 'Page A' and 'Page B' or something. do you have two popup pages showing at the same time?

@innomotionmedia sorry I haven't really gotten to this, with what's going on at work I have been lax about this project and its bugs. I'll try and see if I can figure it out tonight

beeradmoore commented 3 years ago

My bad. A good breakdown similarly to how our app works is kind of like Twitter works.

FeedA = List of tweets. PageA = Tweet page, displays your tweet and its replies. SettingsA = RG PopupPage only displayed on tapping navigation item in PageA. Is used as a popup menu from the bottom with basic options like delete, share, etc (in this case the share is what prompts the native share dialog) PageB = Tweet analytics page, displays analytics from the tweet you were previously not. Not accessed via SettingsA but instead from a button on PageA.

Open app, presented with a FeedA. Clicking one takes you to PageA. (Xamarin.Forms Navigation.Push) Clicking a navbar item presents SettingsA. Clicking "Share" displays a native share dialog in front of SettiingsA.

Close the app.

Open app, presented with FeedA. Clicking one takes you to PageA. (Xamarin.Forms Navigation.Push) Clicking the analytics button displays PageB. (Xamarin.Forms PushModal) Dismiss PageB with its own close button. Clicking a navbar item presents SettingsA. Clicking "Share" displays a native share dialog behind SettiingsA.

Oddly enough it seems to stay in this odd broken state. Navigate back to FeedA. Click any other item to go to PageA. Clicking "Share" displays a native share dialog behind SettiingsA. (even without going to PageB from PageA again)

I'll see if I can repro on the weekend.

innomotionmedia commented 3 years ago

I fixed this issue by simply not using iOS Alert but Xamarin.Forms Alert 👍 await DisplayAlert(Title, body, button1, button2).

This is rendered infront of popup. Means that the user has to disable it themselfes, but its fine.

beeradmoore commented 3 years ago

So I went to repro this and found that Xamarin Essentials has a Share system. Figured I'd use this rather than my own dependency service and custom share code. Whipped up repro to post and.. works fine 😅. Add in my iOS share code, now its broken.

In my sample attached below you can swap between the two by changing what share code is called in Share in SettingsPopupPage.xaml.cs. If you use the DependencyService method then I think the problem comes from GetViewControllerToDisplayOn in NativeDialogOverlayIssue.iOS/DependencyService/Share.cs. Probably not getting the correct window or view controller that RG Popups is using.

This may explain the behaviour @innomotionmedia was seeing. If so the problem isn't with RG Popups, but with peoples own "get top most page" code and it not selecting the top most RG Popup page. If that is the case then this should be closed.

NativeDialogOverlayIssue.zip

EDIT: Also after looking at our own code I noticed that when we get to our page in the constructor, we use MessagingCenter.Subscribe and then in OnDissapearing we remove it. This is why I was having the odd behaviour of this only happens when you go to another page first. If you bring up the share dialog our custom code was dismissing the PopupPage itself before presenting the share dialog so it appeared to be working correctly.

LuckyDucko commented 3 years ago

@beeradmoore I don't think you let NativeDialogOverlayIssue.zip complete its upload.

This is still a good thing to keep track of, and thank you for your research into this.

beeradmoore commented 3 years ago

@LuckyDucko , that was odd. Fixed it while I was adding that edit to explain my weird behaviour I was seeing.

EmilAlipiev commented 3 years ago

I have similar problem but how do you understand that they are rendered behind? i have exactly same code and i dont see any Toast message is displayed. on Android and Uwp works fine.

florian-berger commented 2 years ago

I have a similar problem with using the Xamarin.Essentials Web Authentictor. The browser view is always opened behind the Popup and I am unable to find a solution for that.

LuckyDucko commented 2 years ago

Do you open them both at similar times? or do you have it clearly one after the other.

Could you provide an example to work off?

florian-berger commented 2 years ago

No, they are not opened at the same time. There is a very small moment between opening the popup and displaying the authentication.

Unfortunately, I am unable to reproduce the issue in a sample project. I will try it for a few hours and if I am able to reproduce it, I will attach an example.

// I figured it out. The popup and the authentication were triggered exactly at the same time, and the popup takes a little bit longer to be opened. Now I am waiting for it to be opened before starting the auth and everything works. 👍

ali-h2010 commented 2 years ago

Is there any solution to make the popup screen behind the modal page? I want to keep the state of the modal page so popping it and showing it again is difficult