locked
How to navigate to a page and reset the 'stack' RRS feed

  • Question

  • User29306 posted

    My app has a few introductory screens for first launch. Once the user gets through these, I want to transition the user to the "main screen" in a way where the back button will not take the user back to the opening screens. How can this be achieved in Xamarin.Forms?

    Monday, June 2, 2014 12:37 PM

All replies

  • User16566 posted

    The suggestions I have seen elsewhere in this forum and in the samples is that you use the .PopModalAsync() and .PushModalAsync() methods to display your intro screen(s), but I can't get these to work the way they should.

    When I call await Navigation.PushModalAsync(new LoginPage()); it displays the Login page as expected, but then I simply press back and I get back to the calling page. I wanted it to stay 'Modal' until I call Navigation.PopModalAsync()

    Hopefully someone can provide guidance.

    Monday, June 2, 2014 3:33 PM
  • User29306 posted

    I haven't been able to figure out the difference between a modal and non-modal page.

    Tuesday, June 3, 2014 3:43 AM
  • User352 posted

    On WinPhone absolutely nothing at all. WinPhone supports global navigation only.

    On iOS/Android lets assume the case of a NavigationPage containing a single content page. If you do a normal push the pushed page will go onto the navigation pages stack. The navigation page will remain visible (this means the top bar that comes with a navigation page remains visible). If you push modal, the entire screens contents will be replaced, the top bar will be hidden/etc.

    In essence a modal push replaces the full screens contents, a normal push replaces the NavigationPage's contents. Except on WinPhone which only supports global nav. There its a full page replace no matter what.

    Tuesday, June 3, 2014 3:56 AM
  • User29306 posted

    Thanks. I don't care about WinPhone because my WinPhone app is now 8.1 XAML based (wpa81) and evidently Xamarin.forms doesn't support that (yet?). Your info about modal pushes sounds like my solution might be to initialize my NavigationPage to my ordinary Main page, and then immediately do a PushModal for my first intro screen when that's appropriate. When the intro screen flow is complete, I can PopModal and the user is then in the right state for the main experience. Am I piecing this together right?

    Tuesday, June 3, 2014 4:02 AM
  • User352 posted

    thats 100% correct and the normal way to do things. As for 8.1 support, the produced app does run on 8.1, but correct you cant write custom renderers targeting the new API's yet. We unfortunately had no time to forward port after MS made their release.

    Tuesday, June 3, 2014 4:05 AM
  • User29306 posted

    Thanks, Jason. BTW, by 8.1 support I meant wpa81, or a Windows Phone 8.1 app targeting WinRT instead of Silverlight. And it appears there is no support for that yet in Xamarin.Forms.

    Monday, June 9, 2014 3:23 PM
  • User7600 posted

    Is it possible to manipulate the navigation stack, either by Forms or by native implementation. I need to remove a some pages from my stack at a certain point - issue is that Android has a hardware back button so I need to be able to remove these. Any suggestions?

    Monday, June 30, 2014 11:11 AM
  • User112 posted

    I am trying to solve this same issue right now (back button). My current solution is, since Forms won't give me the top modal page, to track the viewmodel (using Stack) when doing PushModalAsync, so I know what viewmodel is on top. Then I simply catch Activity's OnBackPressed and delegate it to top viewmodel.

    Wednesday, July 23, 2014 8:10 AM
  • User50392 posted

    This is a pretty massive problem, and I haven't found a proper solution using xamarin forms. I was using the method Andrew outlined, but this does not work properly on android, where a modal (the log in page) can be removed with the hardware back button. Is there currently any way to present a page (modally or not), which the user cannot navigate back from?

    Or is there at least something in the works? Its a bit of an issue when displaying a log in screen (which most apps need) is such a problem.

    Wednesday, August 20, 2014 1:42 AM
  • User14 posted

    Check out this login demo which displays only the login page initially and re-sets the app's root page only on a successful login.

    Wednesday, August 20, 2014 6:44 PM
  • User69617 posted

    Craig - GREAT demo reference. +10 bonus points for you.

    The problem I was running into with the modal solution was that it flashes the main page as the modal pops up. This solution is smooth as ice.

    Friday, September 5, 2014 2:35 PM
  • User112 posted

    The demo is nice but it is just a workaround the fact that page navigation is seriously lacking features. Like reset. The same would be easily done on platform independent level if there was a method Navigation.Reset.

    Friday, September 5, 2014 2:43 PM
  • User69617 posted

    Navigation.PopToRootAsync() ?

    Friday, September 5, 2014 3:18 PM
  • User112 posted

    I don't think that'd work in case where you first show login screen and only after successful login you navigate to main page. (as in the demo)

    Friday, September 5, 2014 3:26 PM
  • User80648 posted

    A very helpful stack overflow article: http://stackoverflow.com/questions/25165106/how-do-you-switch-pages-in-xamarin-forms

    Thursday, October 23, 2014 2:56 PM
  • User55249 posted

    Was there any progress on this matter? In the same way, I have a login screen that I only want to be accessed to through a top-right 3-dot menu. (android) Pushing back shows it if it's modal and pushing the top-left back button shows it too if not modal.

    We're still searching for another thing too, we're trying to change the MasterDetail top-left icon for a .png (a three bar standard menu) that opens the Master menu.

    Wednesday, December 10, 2014 8:42 PM
  • User55249 posted

    Maybe I found a solution (couldn't find it elsewhere)!

    `void btnLoginClicked(Object sender, EventArgs EventArgs){ var activityIndicator = this.FindByName("actIndicator"); actIndicator.IsRunning = true;

        actIndicator.IsRunning = false;
        App.Current.MainPage = new HomePage ();
    

    }`

    Please give us the reference links if anything about this topic is elsewhere!

    PS: I don't know why the markdown is letting me down.

    Wednesday, December 10, 2014 8:46 PM
  • User103830 posted

    This is a useful blog post on the topic http://www.jfarrell.net/2015/01/xamarin-forms-navigation-current-state.html

    Friday, January 30, 2015 12:25 PM
  • User112361 posted

    Solved the problem of removing the login page with this:

    async void onLoginClick(object sender, EventArgs e) { await Navigation.PushAsync(new MainView()); Navigation.RemovePage(this); }

    It seems to work on WP and Android

    Friday, March 6, 2015 3:21 PM
  • User52634 posted

    Hey there,

    For resetting the navigation page I use: while (Navigation.NavigationStack.Count > 0) Navigation.RemovePage (Navigation.NavigationStack.ElementAt (0));

    Friday, March 13, 2015 1:42 PM
  • User71406 posted

    Another approach that worked for me:

    Navigation.InsertPageBefore (new MainPage(), this);
    Navigation.PopAsync ();
    
    Tuesday, April 7, 2015 8:27 PM
  • User119291 posted

    @ashalva Your solution doesn't seem to work on Android with Modal views. This is the problem I'm facing right now.

    I'm trying to have a flow in the pages like this :

    LoginPage -> LoginAuthPage (Xamarin.Auth) + Renderer -> (User logs in) -> TabbedPage

    I'm facing two issues. The first is, if I want to keep this flow, the user will be able to get back to the LoginPage by pressing the back button 2 times, and only the third will exit the app. The second issue is that I can't remove the Pages in the stack, because they are Modal and RemovePage throws an exception when doing it.

    Solution : Override the Back button behavior ? Reset the stack in another way ?

    I've tried another solution like this :

    TabbedPage => Redirected to (*) => LoginPage -> LoginAuthPage (Xamarin.Auth) + Renderer -> (User logs in) -> Back to TabbedPage (PopToRoot)

    • : By specifying my Pages in TabbedPage as BaseContentPage, it checks if the user is logged or not in the "OnAppearing" event, and push the LoginPage in the stack if needed.

    The issues I'm facing here is that I can't PopToRoot the ModalStack (it throws an exception saying it is not globally supported). The other one is the same as the first try, I can't reset the stack and I "can't" hardcode the number of Pops I have to do until reaching the TabbedPage.

    So I'm asking you, what do you think about this case ? And do you have any ideas ? Comments are also welcome.

    Wednesday, April 22, 2015 8:57 AM
  • User119291 posted

    By using the second way I mentionned, I used this :

    while (Navigation.ModalStack.Count > 1) Navigation.PopModalAsync();

    Where "1" corresponds to my TabbedPage. It works, but I don't like the way we have to handle these cases.

    Wednesday, April 22, 2015 9:02 AM
  • User78372 posted

    Resetting MainPage does the trick of forgetting all previous pages, no visual back button on Top Navigation Bar, and does not go back to previous page if Hardware backbutton of Android is Pressed.

    App.Current.MainPage = new NavigationPage(new MyContentPage());
    
    Wednesday, July 22, 2015 7:45 AM
  • User106238 posted

    Ankur, works like a charm.

    Any issues regarding leaks or whatever?

    Wednesday, July 29, 2015 6:41 AM
  • User78372 posted

    @Franc ,

    I haven't seen any issues, nor have I specifically checked if it leaks to memory leaks. Any specific reason you were concerned for Memory leaks with this code snippet?

    Wednesday, July 29, 2015 6:47 AM
  • User57571 posted

    @Ankur I owe you a beer! Thanks for your solution.

    Friday, July 31, 2015 1:14 AM
  • User182157 posted

    Hi,

    Xamarin.IOS Application Close Issue Using Navigation.PopAsync();

    Application closing issue whenI try to move back to previous page. When I clicking button to move to the previous page (Current Page is ContentPage and Previous Page is Tabbed Page) , app getting closed. But its working properly on Android & Windows Phone.

    await Navigation.PopAsync(true); Navigation.RemovePage(this);

    NavigationStack containing 4 Page.

    Tuesday, December 22, 2015 7:05 AM
  • User182157 posted

    @CraigDunn Xamarin.IOS Application Close Issue Using Navigation.PopAsync();

    Application closing issue whenI try to move back to previous page. When I clicking button to move to the previous page (Current Page is ContentPage and Previous Page is Tabbed Page) , app getting closed. But its working properly on Android & Windows Phone.

    await Navigation.PopAsync(true); Navigation.RemovePage(this);

    NavigationStack containing 4 Page.

    Tuesday, December 22, 2015 7:09 AM
  • User89739 posted

    Is there any way to access the previous Page when I hit the back button? I'd like to refresh the previous view when I hit the back button on the newest page.

    Tuesday, September 20, 2016 2:31 PM
  • User71406 posted

    @Dquaglio said: Is there any way to access the previous Page when I hit the back button? I'd like to refresh the previous view when I hit the back button on the newest page. You can get the previous pages from Navigation.NavigationStack. Btw, refreshing the previous page should be done on the previous page, like overriding OnAppearing(), or attaching to the NavigationPage events.

    Tuesday, September 20, 2016 3:10 PM
  • User244890 posted

    I want to navigate from a MasterDetailPage to the Login Page, when i click the logout button the Login page appears for a second and returns to the MasterDetailPage. How can I make the Login page to stay open??? I'm working on a UWP project

    Tuesday, October 18, 2016 11:22 AM
  • User2148 posted

    @Giggas post a repo

    Tuesday, October 18, 2016 1:29 PM
  • User244890 posted

    @AlessandroCaliaro said: @Giggas post a repo

    private async void Logout_OnClicked(object sender, EventArgs e) { await UserManager.Instance.LogoutAsync(); Application.Current.MainPage = new NavigationPage(new Login()); }

    solved :smiley:

    Thursday, October 20, 2016 9:30 AM
  • User231103 posted

    @SuarezDiego said: Another approach that worked for me:

    Navigation.InsertPageBefore (new MainPage(), this);
    Navigation.PopAsync ();
    

    Brilliant Idea worked for me , thanks Buddy

    Saturday, March 4, 2017 12:48 PM
  • User318788 posted

    @Giggas ,

    The above idea of InsertPageBefore is also great. Another approach would be (MVVM way) - Just posting it here is someone want to use it with MVVM-Prism

    Helpers.Utility.Logout();\\ this method is to kill all your settings OR variables await _navigationService.NavigateAsync("app:///Navigation/Login?appModuleRefresh=OnInitialized");

    where Navigation is alias to your NavigationPage and Login is your view after LogOut

    Note the appModuleRefresh is the key to success :)

    Hope this helps.

    Regards, N Baua

    Friday, June 16, 2017 12:16 PM
  • User335878 posted

    async void LoadLoginPage() { App.Current.MainPage.Navigation.InsertPageBefore(new UserLogin(),this); await Navigation.PushAsync(); }

    Loads Navigation stack with current page and pops the recent pages navigated. Popping of recent pages in navigation stack loads the pages faster.

    Tuesday, September 5, 2017 12:18 PM