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?
Posts
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 callNavigation.PopModalAsync()
Hopefully someone can provide guidance.
I haven't been able to figure out the difference between a modal and non-modal page.
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.
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?
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.
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.
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?
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.
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.
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.
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.
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.
Navigation.PopToRootAsync() ?
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)
A very helpful stack overflow article: http://stackoverflow.com/questions/25165106/how-do-you-switch-pages-in-xamarin-forms
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.Maybe I found a solution (couldn't find it elsewhere)!
`void btnLoginClicked(Object sender, EventArgs EventArgs){
var activityIndicator = this.FindByName("actIndicator");
actIndicator.IsRunning = true;
}`
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.
This is a useful blog post on the topic
http://www.jfarrell.net/2015/01/xamarin-forms-navigation-current-state.html
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
Hey there,
For resetting the navigation page I use:
while (Navigation.NavigationStack.Count > 0) Navigation.RemovePage (Navigation.NavigationStack.ElementAt (0));
Another approach that worked for me:
@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)
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.
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.
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.
Ankur, works like a charm.
Any issues regarding leaks or whatever?
@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?
@Ankur I owe you a beer! Thanks for your solution.
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.
@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.
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 overridingOnAppearing()
, or attaching to the NavigationPage events.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
@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
Brilliant Idea worked for me , thanks Buddy
@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
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
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.