Skip to content

Commit

Permalink
Fixed #1166
Browse files Browse the repository at this point in the history
fixed the navigation logic when navigating within NavigationPages
  • Loading branch information
brianlagunas committed Sep 23, 2017
1 parent ae82cdf commit 62c890c
Show file tree
Hide file tree
Showing 8 changed files with 48 additions and 53 deletions.
4 changes: 1 addition & 3 deletions Sandbox/Xamarin/HelloWorld/HelloWorld/HelloWorld/App.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,7 @@ public class App : PrismApplication

protected override void OnInitialized()
{
NavigationService.NavigateAsync("MyTabbedPage", animated: false);
//44115
//NavigationService.NavigateAsync("MyNavigationPage/MainPage/ViewA/ViewB", animated: false);
NavigationService.NavigateAsync("MyMasterDetail/MyNavigationPage/MainPage", animated: false);
}

protected override void RegisterTypes()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
<StackLayout>
<Button Text="MainPage" Command="{Binding NavigateCommand}" CommandParameter="MyNavigationPage/MainPage" />
<Button Text="ViewA" Command="{Binding NavigateCommand}" CommandParameter="MyNavigationPage/ViewA" />
<Button Text="ViewB" Command="{Binding NavigateCommand}" CommandParameter="MyNavigationPage/ViewB" />
<Button Text="ViewC" Command="{Binding NavigateCommand}" CommandParameter="MyNavigationPage/ViewC" />
<Button Text="ViewB" Command="{Binding NavigateCommand}" CommandParameter="MyNavigationPage/ViewB/ViewC/ViewA" />
<Button Text="ViewC" Command="{Binding NavigateCommand}" CommandParameter="MyNavigationPage/ViewC/ViewB" />
</StackLayout>
</ContentPage>
</MasterDetailPage.Master>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ public MyNavigationPage()

public bool ClearNavigationStackOnNavigation
{
get { return false; }
get { return true; }
}

public void Destroy()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ private void Save()
async void Navigate()
{
CanNavigate = false;
await _navigationService.NavigateAsync("ViewB", useModalNavigation: false);
await _navigationService.NavigateAsync("ViewB/ViewC", useModalNavigation: false);
CanNavigate = true;
}

Expand Down
2 changes: 0 additions & 2 deletions Sandbox/Xamarin/HelloWorld/ModuleA/Views/ViewA.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ public partial class ViewA : ContentPage, IDestructible
public ViewA()
{
InitializeComponent();
//42548
NavigationPage.SetHasBackButton(this, false);
}

public void Destroy()
Expand Down
2 changes: 0 additions & 2 deletions Sandbox/Xamarin/HelloWorld/ModuleA/Views/ViewB.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ public partial class ViewB : ContentPage, IDestructible
public ViewB()
{
InitializeComponent();
//42548
NavigationPage.SetHasBackButton(this, false);
}

public void Destroy()
Expand Down
2 changes: 0 additions & 2 deletions Sandbox/Xamarin/HelloWorld/ModuleA/Views/ViewC.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,6 @@ public partial class ViewC : ContentPage, IDestructible
public ViewC()
{
InitializeComponent();
//42548
NavigationPage.SetHasBackButton(this, false);
}

public void Destroy()
Expand Down
83 changes: 43 additions & 40 deletions Source/Xamarin/Prism.Forms/Navigation/PageNavigationService.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Linq;
using System.Threading.Tasks;
using Xamarin.Forms;
using System.Reflection;

namespace Prism.Navigation
{
Expand Down Expand Up @@ -187,10 +188,12 @@ protected virtual async Task ProcessNavigationForRootPage(string nextSegment, Qu

protected virtual async Task ProcessNavigationForContentPage(Page currentPage, string nextSegment, Queue<string> segments, NavigationParameters parameters, bool? useModalNavigation, bool animated)
{
var nextPage = CreatePageFromSegment(nextSegment);
bool useReverse = UseReverseNavigation(currentPage, nextPage);
var nextPageType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));
bool useReverse = UseReverseNavigation(currentPage, nextPageType);
if (!useReverse)
{
var nextPage = CreatePageFromSegment(nextSegment);

await ProcessNavigation(nextPage, segments, parameters, useModalNavigation, animated);

await DoNavigateAction(currentPage, nextSegment, nextPage, parameters, async () =>
Expand All @@ -205,13 +208,13 @@ protected virtual async Task ProcessNavigationForContentPage(Page currentPage, s
}

protected virtual async Task ProcessNavigationForNavigationPage(NavigationPage currentPage, string nextSegment, Queue<string> segments, NavigationParameters parameters, bool? useModalNavigation, bool animated)
{
{
if (currentPage.Navigation.NavigationStack.Count == 0)
{
await UseReverseNavigation(currentPage, nextSegment, segments, parameters, false, animated);
return;
}

var clearNavigationStack = GetClearNavigationPageNavigationStack(currentPage);
var isEmptyOfNavigationStack = currentPage.Navigation.NavigationStack.Count == 0;

Expand All @@ -232,26 +235,18 @@ protected virtual async Task ProcessNavigationForNavigationPage(NavigationPage c
var nextPageType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(nextSegment));
if (topPage?.GetType() == nextPageType)
{
if(clearNavigationStack)
if (clearNavigationStack)
destroyPages.Remove(destroyPages.Last());

await ProcessNavigation(topPage, segments, parameters, false, animated);
await UseReverseNavigation(topPage, null, segments, parameters, false, animated);
await DoNavigateAction(topPage, nextSegment, topPage, parameters);
}
else
{
// Replace RootPage of NavigationStack
var nextPage = CreatePageFromSegment(nextSegment);
await ProcessNavigation(nextPage, segments, parameters, false, animated);
await DoNavigateAction(topPage ?? currentPage, nextSegment, nextPage, parameters, async () =>
{
var push = DoPush(currentPage, nextPage, false, animated);
if (clearNavigationStack && !isEmptyOfNavigationStack)
currentPage.Navigation.RemovePage(topPage);
await UseReverseNavigation(currentPage, nextSegment, segments, parameters, false, animated);

await push;
});
if (clearNavigationStack && !isEmptyOfNavigationStack)
currentPage.Navigation.RemovePage(topPage);
}

foreach (var destroyPage in destroyPages)
Expand Down Expand Up @@ -471,45 +466,49 @@ protected static bool UseModalNavigation(Page currentPage, bool? useModalNavigat
return useModalNavigation;
}

protected static bool UseReverseNavigation(Page currentPage, Page nextPage)
protected static bool UseReverseNavigation(Page currentPage, Type nextPageType)
{
return currentPage?.Parent is NavigationPage && IsSameOrSubclassOf<ContentPage>(nextPageType);
}

public static bool IsSameOrSubclassOf<T>(Type potentialDescendant)
{
return currentPage?.Parent is NavigationPage && nextPage is ContentPage;
Type potentialBase = typeof(T);
return potentialDescendant.GetTypeInfo().IsSubclassOf(potentialBase)
|| potentialDescendant == potentialBase;
}

protected virtual async Task UseReverseNavigation(Page currentPage, string nextSegment, Queue<string> segments, NavigationParameters parameters, bool? useModalNavigation, bool animated)
{
var navigationStack = new Stack<string>();
var nextPage = CreatePageFromSegment(nextSegment);
if (nextPage is NavigationPage)
{
await DoNavigateAction(currentPage, nextSegment, nextPage, parameters, async () =>
{
await DoPush(currentPage, nextPage, useModalNavigation, animated, false);
});
currentPage = nextPage;
}
else
{

if (!String.IsNullOrWhiteSpace(nextSegment))
navigationStack.Push(nextSegment);
}

var newSegments = new Queue<string>();
var illegalSegments = new Queue<string>();

bool illegalPageFound = false;
foreach (var item in segments)
{
var page = CreatePageFromSegment(item);
if (page is ContentPage)
//if we run itno an illegal page, we need to create new navigation segments to properly handle the deep link
if (illegalPageFound)
{
navigationStack.Push(item);
illegalSegments.Enqueue(item);
continue;
}

var pageType = PageNavigationRegistry.GetPageType(UriParsingHelper.GetSegmentName(item));
if (IsSameOrSubclassOf<MasterDetailPage>(pageType))
{
illegalSegments.Enqueue(item);
illegalPageFound = true;
}
else
{
newSegments.Enqueue(item);
navigationStack.Push(item);
}
}

if (newSegments.Count > 0)
await ProcessNavigation(currentPage, newSegments, parameters, useModalNavigation, animated);

var pageOffset = currentPage.Navigation.NavigationStack.Count;
if (currentPage.Navigation.NavigationStack.Count > 2)
pageOffset = currentPage.Navigation.NavigationStack.Count - 1;
Expand All @@ -518,13 +517,17 @@ protected virtual async Task UseReverseNavigation(Page currentPage, string nextS
while (navigationStack.Count > 0)
{
var segment = navigationStack.Pop();
nextPage = CreatePageFromSegment(segment);
var nextPage = CreatePageFromSegment(segment);
await DoNavigateAction(currentPage, segment, nextPage, parameters, async () =>
{
await DoPush(currentPage, nextPage, useModalNavigation, animated, insertBefore, pageOffset);
});
insertBefore = true;
}

//if an illegal page is found, we force a Modal navigation
if (illegalSegments.Count > 0)
await ProcessNavigation(currentPage.Navigation.NavigationStack.Last(), illegalSegments, parameters, true, animated);
}

protected virtual Task DoPush(Page currentPage, Page page, bool? useModalNavigation, bool animated, bool insertBeforeLast = false, int navigationOffset = 0)
Expand Down

0 comments on commit 62c890c

Please sign in to comment.