locked
iOS and Android different behaviors for OnAppearing RRS feed

  • Question

  • User58005 posted

    Hello!

    I am running into an issue (one that I could probably resolve a different way, but I wanted to make sure this is an issue) where when OnAppearing gets called is different for Android and iOS.

    As an example, I have a root TabbedPage, and then I PushModalAsync a LoginPage (ContentPage) on top of it, and afterwards PopModalAsync. For iOS, the OnAppearing method for the TabbedPage seems to get called when the TabbedPage gets created, as well as when the LoginPage gets popped. This makes sense to some extent according to the documentation as the TabbedPage is probably "visible" initially that I can't actually see, then LoginPage is pushed immediately, then when popped, the TabbedPage is visible again. (Just FYI, the documentation for OnAppearing says "When overridden, allows application developers to customize behavior immediately prior to the Xamarin.Forms.Page becoming visible."

    For Android though, the OnAppearing method gets called at the beginning, but not again when after the PopModalAsync. Has anyone else ran into this behavior? Anyone know at least a quick solution for now (as in a way to force call OnAppearing on the TabbedPage from the LoginPage)?

    Thank you!

    Wednesday, June 18, 2014 11:33 PM

All replies

  • User57463 posted

    I have the same issue but having a simple ContentPage as the root instead of TabbedPage.

    My problem occurs when Pushing and then Poping ModalAsync the login page programatically without user interaction. After a failed pop even user initiated pops fail.

    Thursday, June 19, 2014 11:28 AM
  • User43684 posted

    Android is not hitting OnAppearing once the Modal page is popped.

    example: button.Clicked += (sender, e) => Navigation.PopModalAsync();

    Anyone from Xamarin care to comment?

    Friday, July 25, 2014 7:30 PM
  • User33193 posted

    I am also looking for a fix. The reason is listed in the docs.

    Note that on the Android platform, Xamarin.Forms.INavigation operations do not generate activity lifecycle notifications. For each Xamarin.Forms.Page that you push or pop, the Android implementation of Xamarin.Forms.NavigationPage simply adds or removes the content of the page to or from a single activity.

    Monday, August 4, 2014 9:38 AM
  • User65128 posted

    This is still a problem (Xamarin.Forms.1.2.2.6243) is this a bug? will it be fixed? is there a workaround?

    Wednesday, September 3, 2014 1:51 PM
  • User14 posted

    I believe this is the same as this bug report which is marked as confirmed but not currently fixed.

    Thursday, September 4, 2014 7:22 PM
  • User88968 posted

    I got the same issue, any update on this or some workaround?

    Saturday, December 6, 2014 1:59 AM
  • User89791 posted

    This still seems to be an issue. The only workaround I can think of is to create a public method that calls OnAppearing, then have

    if (Device.OS == TargetPlatform.Android)
        previousPage.CallOnAppearing();
    await Navigation.PopModalAsync();
    

    but then you'd have to pass parent pages into Modals.

    Thursday, January 8, 2015 6:31 PM
  • User110660 posted

    No need to pass your parent page into your modal, instead you can keep a reference when you push the modal and define a delegate which calls your OnAppearing when the modal is disappearing.

    ContentPage loginModal = new ContentPage(); loginModal.Disappearing += (sender, e) => { this.OnAppearing(); }; ToolbarItems.Add (new ToolbarItem {
    Text = "Log In",
    Command = new Command (() > {
    Navigation.PushModalAsync (loginModal);
    })
    });

    Thursday, February 26, 2015 10:09 AM
  • User25553 posted

    You could also use the Xamarin.Forms MessagingCenter: http://developer.xamarin.com/guides/cross-platform/xamarin-forms/messaging-center/. It actually comes in handy in a lot of scenarios. You could publish a message during the PopModalAsync() and then subscribe to it in the ContentPage to build its content. But I agree, I'd really like OnAppearing() in Xamarin.Forms to function on Android the same way that it does on iOS. This actually just bit me again yesterday and it wasn't until I read this post that I remembered that OnAppearing() isn't going to work for me on Android.

    Wednesday, May 13, 2015 3:56 PM
  • User130334 posted

    Wow. Thank you @Matt.Cook for reporting this issue in a very concise and precise manner. I jumped pretty quickly to your thread from the search engine. I've been investigating the differences in behaviour between my Android and iOS app for about ten hours before I realized the OnAppearing was behaving differently on iOS and Android.

    Behaviour should be the same. OnAppearing verb clearly comes from the iOS ViewController lifecycle. And yet, the behaviour should be the same on iOS and Android. Otherwise we will be forced to write platform-specific workarounds. And I think that's precisely what Xamarin.Forms is for: Avoid writing platform-specific code.

    Thank you @GustafEriksson for the workaround suggestion.

    Friday, July 31, 2015 7:20 AM
  • User130334 posted

    Please note: @GustafEriksson 's workaround works fine. Be aware that it works only if you back to your main view after login. Don't know what would happen if you send your user to another view from login (another view displaying information about login or login errors for example). It may work well thanks to the push/pop design pattern but keep this in mind in case you do something out of the ordinary.

    Friday, July 31, 2015 7:40 AM
  • User89515 posted

    Did this issue been solved?

    I'm having a similar issue...

    I have also a TabbedPage which has as childrens a NavigationPage each...

    When pushing more than one page into the navigation. When I change a tab and back again, it calls the OnAppering of every Pages in the StackNaviagation.

    And then when I pop one of them the OnAppearing is not called again.

    The pages were not Pushed in Modal way. I used just PushAsync.

    Is this a bug?

    Tuesday, April 26, 2016 4:41 PM
  • User179286 posted

    Yes it is in Android. OnAppering does not get called when a Page is exposed by popping the page above. It's already been reported.

    Tuesday, April 26, 2016 6:02 PM
  • User89515 posted

    @ThomasBukhart Thanks for the answer. Hope it get solved soon.

    If someone needs... My workaround for this, which don't need to reference the parentPage was:

     public class CustomNavigationPage : NavigationPage
        {
    
    
            public CustomNavigationPage(Page pag)
            {
                this.Navigation.PushAsync (pag);
    
                //Only in Android
                #if __ANDROID__
                Popped +=  (sender, e) => {
                            ((BasePage)this.Navigation.NavigationStack[this.Navigation.NavigationStack.Count - 1]).CallOnAppearing();
                };
                #endif
            }
    
        }  
    
    public class BasePage : ContentPage
        {
            public BasePage ()
            {
            }
    
    
            #if __ANDROID__
            public void CallOnAppearing()
            {
                this.OnAppearing ();
            }
            #endif
        } 
    

    This consist in change the Popped event from NavigationPage, that is called every time after a page is popped, to call the OnAppearing of the page.

    Hope it help! :)

    Tuesday, April 26, 2016 8:37 PM
  • User130334 posted

    It's supposed to have been fixed in 2.1.0 but I haven't tested yet: https://bugzilla.xamarin.com/show_bug.cgi?id=32615

    Thursday, April 28, 2016 10:56 AM
  • User40046 posted

    Its still not fixed...

    I created a post detailing the problem and included a sample solution. https://forums.xamarin.com/discussion/69804/onappearing-still-not-firing-after-modalpop-in-droid-applications-sample-included#latest

    Tuesday, July 5, 2016 3:55 PM
  • User42522 posted

    But my experience is different. I only find the sequence of calls to Parent.OnAppearing() and Current.OnDisappearing() are different between Android and other platforms as I discussed here.

    Tuesday, July 5, 2016 5:22 PM
  • User130334 posted

    I have just updated from Forms 1.5.1 to 2.3.1 and OnAppearing is now called on Android when I perform a PopModalAsync

    Thursday, August 18, 2016 2:38 PM
  • User224828 posted

    Yes, but not when you PopToRootAsync (not modal). This means it's only partly fixed ...

    Friday, October 14, 2016 3:40 PM
  • User152872 posted

    The OnAppearing behaviour for android when turning off and on the screen is out of my expectation:

    1.) When removing a page using INavigation.RemovePage(page), the removed page will still receive OnAppearing call when the screen is off and on. This happen even when the page is not part of any view tree. Using PopAsync to remove a page will not have this problem.

    2.) When turning off and turning back on screen, OnAppearing will invoked for all pages in navigation stack (and also those pages removed by INavigation.RemovePage as mention on top). I would expect only the top most page's OnAppearing gets call, but it is not.

    Is my expectation wrong?

    PS: I can reproduce this behaviour in my simple test project that is using Xamarin.Forms v2.3.3.168.

    Tuesday, December 6, 2016 10:22 AM
  • User277020 posted

    @AlbertTan i'm facing some issues related to your second point. My App has two behaviours that call OnAppearing for all pages in navigation stack. The first one is the same as yours, when turning off and turning back on the screen. The second one i can't even understand why it's happening. The app i'm developing is designed to a Motorola Symbol handheld, it was necessary to implement some behaviours related to the physical barcode scanner, i'm using DependecyServices and Intents(Android side), everytime a barcode is read, the OnAppearing method for all pages in navigation stack are called. The way i found to avoid these two issues was add a page verification in each OnAppearing method like this:

    protected override void OnAppearing()
    {
        if (PageFactory.Instance.CurrentPage == this)
        {
            base.OnAppearing();
            LoadForm();
        }
    }
    

    I've been working on Cross-Platfform for almost 6 years using another technology and, for me, it's not a good approach to avoid this problem, but is the only one i found so far.

    I'd appreciate if anyone could explain me these behaviours :)

    Thursday, December 29, 2016 12:45 PM
  • User367994 posted

    It's 2018 and still this issue exist? :/ :/ :/ In UWP and Android my OnAppearing() work fine but in iOS don't trigger unless I click on some entry or button :/ :/ I read your posts but I didn't find a solution, How you guys fixed it at the end?

    Wednesday, May 2, 2018 7:01 AM
  • User371160 posted

    i'm having the same issue, did anyone find a solution? thanks

    Saturday, October 13, 2018 7:50 AM
  • User388648 posted

    2020 and this is still an issue for iOS. Any workaround rather than using a custom nav page for Android only?

    Thursday, March 26, 2020 10:02 PM
  • User76049 posted

    Shout here so the don't spend all their time tinkering with Shell which benefits a few https://github.com/xamarin/Xamarin.Forms/issues/2210

    Thursday, March 26, 2020 11:45 PM