Skip to content
This repository was archived by the owner on May 1, 2024. It is now read-only.

Commit

Permalink
fix modal onappearing and hardware back button (#10189)
Browse files Browse the repository at this point in the history
  • Loading branch information
PureWeen authored Apr 3, 2020
1 parent e0a4e2e commit d416057
Show file tree
Hide file tree
Showing 5 changed files with 96 additions and 39 deletions.
30 changes: 25 additions & 5 deletions Xamarin.Forms.Core.UnitTests/ShellLifeCycleTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -562,12 +562,31 @@ public override void Setup()
Routing.RegisterRoute("LifeCyclePage", typeof(LifeCyclePage));
}

class ShellLifeCycleState
public class ShellLifeCycleState
{
public bool ItemAppearing;
public bool SectionAppearing;
public bool ContentAppearing;
public bool PageAppearing;
public bool ItemAppearing
{
get;
set;
}

public bool SectionAppearing
{
get;
set;
}

public bool ContentAppearing
{
get;
set;
}

public bool PageAppearing
{
get;
set;
}

public ShellLifeCycleState(Shell shell)
{
Expand Down Expand Up @@ -608,6 +627,7 @@ public void AllFalse()
Assert.IsFalse(ContentAppearing);
Assert.IsFalse(PageAppearing);
}

public void AllTrue()
{
Assert.IsTrue(ItemAppearing);
Expand Down
32 changes: 31 additions & 1 deletion Xamarin.Forms.Core.UnitTests/ShellModalTests.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System.Text;
using System.Threading.Tasks;
using NUnit.Framework;
using Xamarin.Forms.Internals;

namespace Xamarin.Forms.Core.UnitTests
{
Expand Down Expand Up @@ -269,7 +270,25 @@ public async Task PushingContentPageToNonNavigationPageThrowsException()

Assert.IsTrue(invalidOperationThrown);
}



[Test]
public async Task AppearingAndDisappearingFiresOnShellWithModal()
{
Shell shell = new Shell();
shell.NavigationProxy.Inner = new NavigationProxy();
var lifeCyclePage = new ShellLifeCycleTests.LifeCyclePage();
shell.Items.Add(CreateShellItem(lifeCyclePage, shellItemRoute: "item", shellSectionRoute: "section", shellContentRoute: "content"));

var shellLifeCycleState = new ShellLifeCycleTests.ShellLifeCycleState(shell);
await shell.GoToAsync("ModalTestPage");
await shell.Navigation.ModalStack[0].Navigation.PopModalAsync();
shellLifeCycleState.AllTrue();
await shell.GoToAsync("ModalTestPage");
shellLifeCycleState.AllFalse();
}


[Test]
public async Task IsAppearingFiredOnLastModalPageOnly()
{
Expand Down Expand Up @@ -340,6 +359,17 @@ public ModalTestPageBase()
{
Shell.SetPresentationMode(this, PresentationMode.Modal);
}

protected override void OnAppearing()
{
base.OnAppearing();
}


protected override void OnParentSet()
{
base.OnParentSet();
}
}

public class ModalTestPage : ModalTestPageBase
Expand Down
44 changes: 35 additions & 9 deletions Xamarin.Forms.Core/Shell/Shell.cs
Original file line number Diff line number Diff line change
Expand Up @@ -452,7 +452,7 @@ public Task GoToAsync(ShellNavigationState state, bool animate)
internal async Task GoToAsync(ShellNavigationState state, bool? animate, bool enableRelativeShellRoutes)
{
// FIXME: This should not be none, we need to compute the delta and set flags correctly
var accept = ProposeNavigation(ShellNavigationSource.Unknown, state, true);
var accept = ProposeNavigation(ShellNavigationSource.Unknown, state, this.CurrentState != null);
if (!accept)
return;

Expand Down Expand Up @@ -969,7 +969,10 @@ protected override bool OnBackButtonPressed()
currentContent.Navigation.PopAsync();
return true;
}
return false;

var args = new ShellNavigatingEventArgs(this.CurrentState, "", ShellNavigationSource.Pop, true);
OnNavigating(args);
return args.Cancelled;
}

bool ValidDefaultShellItem(Element child) => !(child is MenuShellItem);
Expand Down Expand Up @@ -1314,31 +1317,54 @@ class NavigationImpl : NavigationProxy

protected override void OnRemovePage(Page page) => SectionProxy.RemovePage(page);

protected override Task<Page> OnPopModal(bool animated)
protected override async Task<Page> OnPopModal(bool animated)
{
if (ModalStack.Count > 0)
ModalStack[ModalStack.Count - 1].SendDisappearing();

if (!_shell.CurrentItem.CurrentItem.IsPoppingModalStack)
{
if (ModalStack.Count == 1)
_shell.CurrentItem.SendAppearing();
else if (ModalStack.Count > 1)
if (ModalStack.Count > 1)
ModalStack[ModalStack.Count - 2].SendAppearing();
}

return base.OnPopModal(animated);
var modalPopped = await base.OnPopModal(animated);

if (ModalStack.Count == 0 && !_shell.CurrentItem.CurrentItem.IsPoppingModalStack)
_shell.CurrentItem.SendAppearing();

return modalPopped;
}
protected override Task OnPushModal(Page modal, bool animated)

protected override async Task OnPushModal(Page modal, bool animated)
{
if (ModalStack.Count == 0)
_shell.CurrentItem.SendDisappearing();

if (!_shell.CurrentItem.CurrentItem.IsPushingModalStack)
modal.SendAppearing();

return base.OnPushModal(modal, animated);
await base.OnPushModal(modal, animated);

modal.NavigationProxy.Inner = new NavigationImplWrapper(modal.NavigationProxy.Inner, this);
}


class NavigationImplWrapper : NavigationProxy
{
readonly INavigation _shellProxy;

public NavigationImplWrapper(INavigation proxy, INavigation shellProxy)
{
Inner = proxy;
_shellProxy = shellProxy;

}

protected override Task<Page> OnPopModal(bool animated) => _shellProxy.PopModalAsync(animated);

protected override Task OnPushModal(Page modal, bool animated) => _shellProxy.PushModalAsync(modal, animated);
}
}
}
}
20 changes: 0 additions & 20 deletions Xamarin.Forms.Core/Shell/ShellSection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -889,26 +889,6 @@ class NavigationImpl : NavigationProxy
protected override Task OnPushAsync(Page page, bool animated) => _owner.OnPushAsync(page, animated);

protected override void OnRemovePage(Page page) => _owner.OnRemovePage(page);

protected override Task<Page> OnPopModal(bool animated)
{
if(ModalStack.Count == 1)
{
_owner.PresentedPageAppearing();
}

return base.OnPopModal(animated);
}

protected override Task OnPushModal(Page modal, bool animated)
{
if (ModalStack.Count == 0)
{
_owner.PresentedPageDisappearing();
}

return base.OnPushModal(modal, animated);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -59,8 +59,9 @@ void ViewPager.IOnPageChangeListener.OnPageSelected(int position)
{
UpdateCurrentItem(shellContent);
}
else
else if(shellSection?.CurrentItem != null)
{
var currentPosition = SectionController.GetItems().IndexOf(shellSection.CurrentItem);
_selecting = true;

// Android doesn't really appreciate you calling SetCurrentItem inside a OnPageSelected callback.
Expand All @@ -69,10 +70,10 @@ void ViewPager.IOnPageChangeListener.OnPageSelected(int position)

Device.BeginInvokeOnMainThread(() =>
{
if (position < _viewPager.ChildCount && _toolbarTracker != null)
if (currentPosition < _viewPager.ChildCount && _toolbarTracker != null)
{
_viewPager.SetCurrentItem(position, false);
UpdateCurrentItem(shellContent);
_viewPager.SetCurrentItem(currentPosition, false);
UpdateCurrentItem(shellSection.CurrentItem);
}

_selecting = false;
Expand Down

0 comments on commit d416057

Please sign in to comment.