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

Fix layout size when iOS swipe-back gesture is aborted, fixes #14763 #14892

Closed
wants to merge 5 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
using System.Linq;
using System.Threading.Tasks;
#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif

namespace Xamarin.Forms.Controls.Issues
{
#if UITEST
[NUnit.Framework.Category(Core.UITests.UITestCategories.Github10000)]
#endif
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 14763, "[iOS] Resize on back-swipe stays when going back is cancelled", PlatformAffected.iOS)]
public class Issue14763 : TestNavigationPage
{
public Issue14763() : base()
{ }

class HomePage : ContentPage
cpraehaus marked this conversation as resolved.
Show resolved Hide resolved
{
public HomePage()
{
Title = "Home";
var grd = new Grid { BackgroundColor = Color.Brown };
grd.RowDefinitions.Add(new RowDefinition());
grd.RowDefinitions.Add(new RowDefinition());
grd.RowDefinitions.Add(new RowDefinition());

NavigationPage.SetHasNavigationBar(this, false);

var boxView = new BoxView { BackgroundColor = Color.Blue };
grd.Children.Add(boxView, 0, 0);
var stackLayout = new StackLayout()
{
BackgroundColor = Color.Yellow,
AutomationId = "ChildLayout"
};
var btnPop = new Button {
Text = "Back (I get cut off)", AutomationId = "PopButtonId", Command = new Command(async () => await Navigation.PopAsync()),
BackgroundColor = Color.Red
};
stackLayout.Children.Add(btnPop);
btnPop.VerticalOptions = new LayoutOptions(LayoutAlignment.End, expands: true);
var btn = new Button()
{
BackgroundColor = Color.Pink,
Text = "NextButtonID",
AutomationId = "NextButtonID",

Command = new Command(async () =>
{

var page = new ContentPage
{
Title = "Detail",
Content = stackLayout,
AutomationId = "ChildPage"
};

NavigationPage.SetHasNavigationBar(page, true);
await Navigation.PushAsync(page, false);
})
};

grd.Children.Add(btn, 0, 1);
var image = new Image() { Source = "coffee.png", AutomationId = "CoffeeImageId", BackgroundColor = Color.Yellow };
image.VerticalOptions = LayoutOptions.End;
grd.Children.Add(image, 0, 2);
Content = grd;

}
}

protected override void Init()
{
PushAsync(new HomePage());
}

#if UITEST && __IOS__
[Test]
public async Task PopButtonStillVisibleAfterSwipeBack()
{
RunningApp.WaitForElement("NextButtonID");
// Navigate to child page
RunningApp.Tap("NextButtonID");
var childLayout = RunningApp.WaitForElement("ChildLayout").First();
RunningApp.WaitForElement("PopButtonId");
await Task.Delay(1000);
var origLayoutRect = childLayout.Rect;

// Swipe-back/Swipe in from left across 1/2 of screen width to start back nav without completing it
var screenBounds = RunningApp.ScreenBounds();
RunningApp.DragCoordinates(0, screenBounds.CenterY, screenBounds.CenterX, screenBounds.CenterY);
// Wait for swipe-back and UI to settle
await Task.Delay(3000);
childLayout = RunningApp.WaitForElement("ChildLayout").First();
var newLayoutRect = childLayout.Rect;

// Assert that child page has same height as before
Assert.That(newLayoutRect.Height, Is.EqualTo(origLayoutRect.Height));
}
#endif
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue14095.xaml.cs">
<DependentUpon>Issue14095.xaml</DependentUpon>
</Compile>
<Compile Include="$(MSBuildThisFileDirectory)Issue14763.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue14523.xaml.cs">
<DependentUpon>Issue14523.xaml</DependentUpon>
</Compile>
Expand Down Expand Up @@ -1845,6 +1846,7 @@
<Compile Include="$(MSBuildThisFileDirectory)Issue8383.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue8383-2.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue8384.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue8384.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue13577.xaml.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue14505.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue14505-II.cs" />
Expand Down
9 changes: 7 additions & 2 deletions Xamarin.Forms.Platform.iOS/Renderers/NavigationRenderer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -173,10 +173,10 @@ public override void ViewDidLayoutSubviews()
var toolbar = _secondaryToolbar;

//save the state of the Current page we are calculating, this will fire before Current is updated
_hasNavigationBar = NavigationPage.GetHasNavigationBar(Current);
_hasNavigationBar = NavigationPage.GetHasNavigationBar(Current) && !(NavigationBarHidden || NavigationBar.Translucent);

// Use 0 if the NavBar is hidden or will be hidden
var toolbarY = NavigationBarHidden || NavigationBar.Translucent || !_hasNavigationBar ? 0 : navBarFrameBottom;
var toolbarY = !_hasNavigationBar ? 0 : navBarFrameBottom;
toolbar.Frame = new RectangleF(0, toolbarY, View.Frame.Width, toolbar.Frame.Height);

double trueBottom = toolbar.Hidden ? toolbarY : toolbar.Frame.Bottom;
Expand Down Expand Up @@ -1402,6 +1402,11 @@ void UpdateNavigationBarVisibility(bool animated)
current.IgnoresContainerArea = !hasNavBar;
NavigationController.SetNavigationBarHidden(!hasNavBar, animated);
}

// Esnure correct nav bar state and layout dimension after swipe-back gesture was
// aborted, see https://github.com/xamarin/Xamarin.Forms/issues/14763.
if (_navigation.TryGetTarget(out var n))
n.ValidateNavbarExists(current);
}

void UpdateToolbarItems()
Expand Down