OnAppearing() not called on Android for underneath page if page on top was pushed modal

JacobAndersonJacobAnderson USMember
edited January 2016 in Xamarin.Forms

Shared code that was tested on Android and iOS.
Using Xamarin Forms 2.0.0.6490 with a NavigationPage.

Steps to Reproduce:
1.) Set a page as your MainPage for Navigation.
2.) Observe OnAppearing() is called on Android and iOS
3.) Push another page to Navigation with PushModalAsync()
4.) Pop the newly pushed page using PopModalAsync()
5.) Observe OnAppearing() is NOT called on Android for your original MainPage but is on iOS.

If you Push the 2nd page normally instead of modal Android works correctly.

Posts

  • LyndonHugheyLyndonHughey USUniversity ✭✭✭

    I've also noticed this behavior when navigating to a detail page then returning to the master page on android using XF. The master page's OnAppearing() method is not called.

  • AdamMeaneyAdamMeaney USMember ✭✭✭✭✭

    Bug 32615 - [Android] OnAppearing is not called on previous page when modal page is popped

    Fixed in 2.1.0 pre-1

  • LyndonHugheyLyndonHughey USUniversity ✭✭✭

    @AdamMeaney Thanks Adam. It looks like the issue of it not being called when navigating from a child page back to a master (within a tabbedPage on Android) is also a bug. I will submit a report for it.

  • @AdamMeaney

    Since this bugs status is reopened. I noticed that it calls the MainPage.OnAppearing(), but not the page on top's OnAppearing().

    1.) NavigationPage with a MainPage and a 2nd page on top pushed async.
    2.) Push a 3rd page async and Modal
    3.) Pop the 3rd page off async and Modal
    4.) MainPage's OnAppearing is called but not page 2's even though that is the is the page being displayed.

  • AllisterAllister USMember ✭✭

    Anyone seen a workaround to this as the bug is still marked as in progress and not fixed as of forms version 2.1.0.6529.

  • JacobAndersonJacobAnderson USMember

    @Allister said:
    Anyone seen a workaround to this as the bug is still marked as in progress and not fixed as of forms version 2.1.0.6529.

    This is what I use.

    public class XamarinFormsApp : Application
      {
            public XamarinFormsApp ()
            {
                this.ModalPopped += AppModalPopped;
        }
    
        void AppModalPopped (object sender, ModalPoppedEventArgs e)
            {
                Device.OnPlatform(
                    // Android doesn't call OnAppearing for top NavigationPage when popping Modally.
                    Android: AndroidAppModalPopped);
            }
    
            void AndroidAppModalPopped()
            {
               // var navigation = [Accessing your NavigationPage's INavigation goes here];
                int modalNavCount = navigation.ModalStack.Count;
                int navCount = navigation.NavigationStack.Count;
    
                // If there's nothing left on the Modal Stack app will be moving back to the NavStack
                // (Note: The NavigationPage is always the first thing on the ModalStack.)
                if (modalNavCount == 1)
                {
                    // And we should force the top page of the Navigation Page stack to appear
                    PageBaseClass latestPage = navigation.NavigationStack[navCount - 1] as PageBaseClass;
                    if (latestPage != null)
                    {
                        latestPage.ForceAppearing(); // PageBaseClass has a public method exposing OnAppearing()
                    }
                }
            }
      }
    
  • VictorChelaruVictorChelaru USMember ✭✭

    Note that the latest version of XamarinForms seems to fix the ModalStack.Count being at 1 despite there being no items.

    That means the if statement needs to be:

    ...
    if(modalNavCount == 0)
    {
      ...
    
  • NMackayNMackay GBInsider, University mod

    @VictorChelaru said:
    Note that the latest version of XamarinForms seems to fix the ModalStack.Count being at 1 despite there being no items.

    That means the if statement needs to be:

    ...
    if(modalNavCount == 0)
    {
      ...
    

    Good spot, the fixed that in 2.3.0/1 or something, it broke my navigation service too.

  • IamJohnny45IamJohnny45 USMember

    I have a Navigation page which pop's pages on top when triggered by a listview selected event. The page on top then closes itself by firing a Navigation.PopAsync(); but the parent page never calls OnAppearing().

    public class ObjectListPage : NavigationPage  {
            ...
            listView.ItemSelected += (object sender, SelectedItemChangedEventArgs e) => {
                if (e.SelectedItem != null) {
                    var childPage = new ChildPage();
                    PushAsync(childPage);                    
                }
        ....
        protected override void OnAppearing() {
            .... // this code is never executed except the first time the app loads
        }
    }
    
    internal class ChildPage : ContentPage {
        ...
        var closeButton = new Button();
        closeButton.Clicked += (Object sender, TextChangedEventArgs e) => {
            Navigation.PopAsync();
        }
    }
    

    The close button closes the child page returning to the parent as expected, but the OnAppearing event never fires.

    Can anyone else verify that they are still having the same problem, or do I have a mistake in my code?

  • AndrewZaslowAndrewZaslow USUniversity

    We are seeing the same thing but currently only on Windows UWP. This is a pretty big problem for us.

  • Tim.3500Tim.3500 USMember ✭✭

    @JacobAndreasen your post did it for me! Thanks, I have Tabbed Page and after login page PushModelAsync, onAppearing not working on the sSetting tab, had to add code on the OnAppearing on the MainTabbed page and mine worked... thanks!

  • Unpredictable crap. One would expect OnAppearing to fire the moment the page underneath is popped into view.
    Needed this for some light dark theme switchiug.
    AFter I switch the themje to dark more, the pages that get pused change color but when you pop back lo and behold pages stored prior to in the stack do not get the styling changes.
    Yet another curveball thrown by the great Xamarin forms.

  • EddieMEddieM USMember ✭✭
    edited February 13

    In short. For those that are having this issue when dealing with modals. I just made sure my PopModalAsync call animated and that fixed the issue for me. Detail below.

    I had this issue happen to me as well. Here is how I had my code set up. Page1 -> Page2 -> Modal1 or Modal2. A MasterDetailPage with a NavigationPage as my root page. From my root page i had another page on the stack(Page2). From that page I had the possibility of opening 1 of 2 modals. Both managed by Page2. The modals did not control themselves. When the user was done using Modal1 they would call the Page2(EventHandler) to switch to Modal2 rather than stacking them. To avoid the user seeing Modal1 close with the Page2 in the background. Then seeing Modal2 open. I made sure that my PushModalAsync provided the second parameter of false to NOT animate. Same with the PopModalAsync call. When ending the process I would first call the PopModalAsync with false to not animate the modal close. Then use Navigation.InsertPageBefore to insert a new page at the 0 index position. Then run Navigation.PopToRootAsync. To get all the other pages off the stack. Now I will assume because my first action before setting the new root page was closing a modal without animating it. When my new root page opened the OnAppearing was not triggered. Just a wild guess. I changed my code so that only in the event I knew I was about to set a new root page after closing the modal. I would call PopModalAsync without the animate parameter which defaults to true. Doing this caused my new root page's OnAppearing to fire which fixed the issue for me.

  • EddieMEddieM USMember ✭✭

    Also, note I had very similar code that fired from a different page where it was the only one on the stack and the issue does not happen. This only happened for me when I had Page1 -> Page2 -> Modal1 or Modal2 on the stack. Then perform the PopModalAsync(false), InsertPageBefore and PopToRootAsync. Page1 -> Modal1 or Modal2 works fine.

Sign In or Register to comment.