Reputation: 7414
When my app starts, I so some logic in my AppDelegate
and assign the MainPage
a page based on the results of that logic.
public override bool FinishedLaunching(UIApplication app, NSDictionary options)
{
global::Xamarin.Forms.Forms.Init ();
// .....
if(authorizationStatus == PhotoLibraryAuthorizationStatus.Authorized)
{
bokehApp.SetStartupView(serviceLocator.GetService<AlbumsPage>());
}
else
{
bokehApp.SetStartupView(serviceLocator.GetService<StartupPage>());
}
}
In my app.cs, I assign the MainPage
the given view from the AppDelegate
public class App : Xamarin.Forms.Application
{
public void SetStartupView(ContentPage page)
{
this.MainPage = new NavigationPage(page);
}
}
In this instance, I am passing StartupPage
into the SetStartupView(Page)
method. When the user does something, I navigate to the AlbumsPage
.
this.Navigation.PushAsync(new AlbumPage());
When I do this, the AlbumPage
is created and navigated to; it's Navigation.NavigationStack
collection only contains itself, not the Page that it just navigated from. What I want to do, is prevent a call to this.Navigation.PopAsync()
navigating back to the StartupPage
, which is what currently happens.
Initially I was going to just run a loop and pop the original Page off, and then remove all of the remaining pages, in this case StartupPage
.
// Grab the current page, as it is about to become our new Root.
var navigatedPages = this.Navigation.NavigationStack.ToList();
Page newRootPage = navigatedPages.Last();
// Dont include the current item on the stack in the removal.
navigatedPages.Remove(newRootPage);
while(navigatedPages.Count > 0)
{
Page currentPage = navigatedPages.Last();
this.Navigation.RemovePage(currentPage);
}
However, when I look, the Navigation.NavigationStack
collection only contains the AlbumsPage
. Yet, calling this.Navigation.PopAsync()
navigates back to the StartupPage
.
What do I need to do in order to reset this navigation stack, so that popping will not navigate back to the initial page?
When I navigate, I've been able to use this:
App.Current.MainPage = new NavigationPage(viewModelPage);
as suggested by @Daniel but this prevents the animation from taking place. I have also tried
await App.Current.MainPage.Navigation.PushAsync(fooPage);
App.Current.MainPage = new NavigationPage(fooPage);
When I do this, I see the new page transitioned to, but once the await call on PushAsync
finishes, and the MainPage
is replaced, the Page disappears and I'm left with an empty screen.
I really don't want to lose the animations during transitioning from my setup Page to the actual app.
Upvotes: 2
Views: 6766
Reputation: 152
This is fix my problem.
protected override bool OnBackButtonPressed()
{
foreach (Page page in Navigation.ModalStack)
{
page.Navigation.PopModalAsync();
}
return true;
}
Upvotes: 1
Reputation: 7414
I was able to solve the issue. This mostly came down to my lack of understanding how the NavigationPage worked. It would seem that each Page is given their own Navigation stack. As I navigated between Pages and examined their NavigationStack
collections, they always just had one item in them.
I then started looking at App.Current.MainPage.Navigation
and discovered that it actually had the entire stack (both StartupPage
and FooPage
). I was able to then grab the StartupPage
prior to pushing the FooPage
onto the navigation stack, and then removing the StartupPage
once the navigation to FooPage
was completed. This essentially let me reset the root page, while keeping the transition animation between the views.
Page originalRootPage = App.Current.MainPage.Navigation.NavigationStack.Last();
await App.Current.MainPage.Navigation.PushAsync(new FooPage());
App.Current.MainPage.Navigation.RemovePage(originalRootPage);
I'll mark this as answered when the time-period has expired and i'm allowed to.
Upvotes: 6
Reputation: 7454
I think what you're looking for is setting:
App.Current.MainPage
to a new NavigationPage
. It replaces main page of application.
Upvotes: 5