--- /dev/null
+using System;
+
+using Xamarin.Forms.CustomAttributes;
+using Xamarin.Forms.Internals;
+
+#if UITEST
+using Xamarin.UITest;
+using NUnit.Framework;
+#endif
+
+namespace Xamarin.Forms.Controls
+{
+ [Preserve(AllMembers = true)]
+ [Issue(IssueTracker.Bugzilla, 39908, " Back button hit quickly results in jumbled pages")]
+ public class Bugzilla39908 : TestContentPage // or TestMasterDetailPage, etc ...
+ {
+ protected override void Init()
+ {
+ var label = "Root Page";
+
+ Title = label;
+ Content = new StackLayout
+ {
+ VerticalOptions = LayoutOptions.Center,
+ Children = {
+ new Label {
+ HorizontalTextAlignment = TextAlignment.Center,
+ Text = label
+ },
+ NewButton ()
+ }
+ };
+ }
+
+
+
+ private Button NewButton()
+ {
+ var newPageButton = new Button();
+ newPageButton.Text = "Another one";
+ newPageButton.Clicked += OnNewPage;
+
+ return newPageButton;
+ }
+
+ private ContentPage NewPage()
+ {
+ var label = Navigation != null ? "Page " + (Navigation.NavigationStack.Count - 1) : "Root Page";
+
+ return new ContentPage
+ {
+ Title = label,
+ Content = new StackLayout
+ {
+ VerticalOptions = LayoutOptions.Center,
+ Children = {
+ new Label {
+ HorizontalTextAlignment = TextAlignment.Center,
+ Text = label
+ },
+ NewButton ()
+ }
+ }
+ };
+ }
+
+ private async void OnNewPage(object sender, EventArgs e)
+ {
+ await Navigation.PushAsync(NewPage());
+ }
+ }
+}
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla39486.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue55555.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Bugzilla41029.cs" />
+ <Compile Include="$(MSBuildThisFileDirectory)Bugzilla39908.cs" />
</ItemGroup>
<ItemGroup>
<EmbeddedResource Include="$(MSBuildThisFileDirectory)Bugzilla22229.xaml">
+++ /dev/null
-using NUnit.Framework;
-
-using Xamarin.UITest;
-using Xamarin.UITest.Android;
-using Xamarin.UITest.Configuration;
-
-namespace Xamarin.Forms.Core.UITests
-{
- internal static class RunningApp
- {
- public static AndroidApp App;
-
- public static void Restart ()
- {
- App = ConfigureApp
- .Android
- .Debug ()
- .ApkFile ("../../../Xamarin.Forms.ControlGallery.Android/bin/Debug/AndroidControlGallery.AndroidControlGallery-Signed.apk")
- .StartApp ();
- }
- }
-}
\ No newline at end of file
<DefineConstants>TRACE;DEBUG;__ANDROID__;UITEST</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>0114;0108;4014;0649;0168;0169;0219</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
</Reference>
- <Reference Include="Xamarin.UITest, Version=1.3.8.0, Culture=neutral, processorArchitecture=MSIL">
+ <Reference Include="Xamarin.UITest">
<HintPath>..\packages\Xamarin.UITest.1.3.8\lib\Xamarin.UITest.dll</HintPath>
- <Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="..\Xamarin.Forms.Core.iOS.UITests\Tests\WebViewUITests.cs">
<Link>Tests\WebViewUITests.cs</Link>
</Compile>
- <Compile Include="App.cs" />
<Compile Include="PlatformQueries.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
<Compile Include="..\Xamarin.Forms.Core.iOS.UITests\Remotes\RemoteFactory.cs">
</Target>
-->
<ItemGroup />
-</Project>
+</Project>
\ No newline at end of file
+++ /dev/null
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-using NUnit.Framework;
-
-using Xamarin.UITest;
-using Xamarin.UITest.iOS;
-
-namespace Xamarin.Forms.Core.UITests
-{
- internal static class RunningApp
- {
- public static iOSApp App;
-
- public static void Restart ()
- {
- App = ConfigureApp
- .iOS
- .Debug ()
- // Keeping the old BundleId for now, Test Cloud doesn't
- // like it when we update the BundleId for an existing app
- .InstalledApp ("com.xamarin.quickui.controlgallery")
- .StartApp (Xamarin.UITest.Configuration.AppDataMode.Clear);
- }
- }
-}
\ No newline at end of file
{
// TODO: Landscape tests
- public static IApp App { get; private set; }
+ public static IApp App { get; private set; }
public string PlatformViewType { get; protected set; }
public bool ShouldResetPerFixture { get; protected set; }
public AppRect ScreenBounds { get; private set; }
- protected BaseTestFixture ()
+ protected BaseTestFixture()
{
ShouldResetPerFixture = true;
}
- protected abstract void NavigateToGallery ();
+ protected abstract void NavigateToGallery();
#pragma warning disable 618
[TestFixtureSetUp]
#pragma warning restore 618
- protected virtual void FixtureSetup ()
+ protected virtual void FixtureSetup()
{
try
{
#pragma warning disable 618
[TestFixtureTearDown]
#pragma warning restore 618
- protected virtual void FixtureTeardown ()
- {
+ protected virtual void FixtureTeardown()
+ {
}
[SetUp]
- protected virtual void TestSetup ()
+ protected virtual void TestSetup()
{
- if (!ShouldResetPerFixture) {
- RelaunchApp ();
+ if (!ShouldResetPerFixture)
+ {
+
+ RelaunchApp();
}
- App.Screenshot ("Begin Test");
}
[TearDown]
- protected virtual void TestTearDown ()
+ protected virtual void TestTearDown()
{
- App.Screenshot ("Test complete");
+
}
- void RelaunchApp ()
+ void RelaunchApp()
{
App = null;
- RunningApp.App = null;
-
- try {
- RunningApp.Restart ();
- } catch (Exception ex) {
- // if at first you dont succeed
- RunningApp.Restart ();
- }
-
- // Wrap the app in ScreenshotConditional so it only takes screenshots if the SCREENSHOTS symbol is specified
- App = new ScreenshotConditionalApp(RunningApp.App);
-
- App.SetOrientationPortrait ();
- ScreenBounds = App.RootViewRect ();
- NavigateToGallery ();
+ App = AppSetup.Setup();
+ App.SetOrientationPortrait();
+ ScreenBounds = App.RootViewRect();
+ NavigateToGallery();
}
}
}
[Test]
public void UnevenListCellTest ()
{
- if (UnevenListTests.ShouldRunTest(RunningApp.App)) {
- var element = App.Query (q => q.Marked ("unevenCellListGalleryDynamic").Descendant (("UITableViewCellContentView"))) [0];
-
- Assert.GreaterOrEqual (element.Rect.Height, 100);
+ if (UnevenListTests.ShouldRunTest(App))
+ {
+ var element = App.Query(q => q.Marked("unevenCellListGalleryDynamic").Descendant(("UITableViewCellContentView")))[0];
+
+ Assert.GreaterOrEqual(element.Rect.Height, 100);
}
}
<DefineConstants>TRACE;DEBUG;__IOS__;UITEST</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
- <TreatWarningsAsErrors>false</TreatWarningsAsErrors>
+ <TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<NoWarn>0114;0108;4014;0649;0169;0168;0219</NoWarn>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<Reference Include="nunit.framework">
<HintPath>..\packages\NUnit.2.6.4\lib\nunit.framework.dll</HintPath>
</Reference>
- <Reference Include="Xamarin.UITest, Version=1.3.8.0, Culture=neutral, processorArchitecture=MSIL">
+ <Reference Include="Xamarin.UITest">
<HintPath>..\packages\Xamarin.UITest.1.3.8\lib\Xamarin.UITest.dll</HintPath>
- <Private>True</Private>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="BaseTestFixture.cs" />
- <Compile Include="App.cs" />
<Compile Include="PlatformQueries.cs" />
<Compile Include="Remotes\BaseViewContainerRemote.cs" />
<Compile Include="Remotes\EventViewContainerRemote.cs" />
</Target>
-->
<ItemGroup />
-</Project>
+</Project>
\ No newline at end of file
return OnPopToRoot(page, animated);
}
- public override UIViewController[] PopToRootViewController(bool animated)
- {
- if (!_ignorePopCall && ViewControllers.Length > 1)
- RemoveViewControllers(animated);
-
- return base.PopToRootViewController(animated);
- }
-
public Task<bool> PopViewAsync(Page page, bool animated = true)
{
return OnPopViewAsync(page, animated);
}
-#if __UNIFIED__
- public override UIViewController PopViewController(bool animated)
-#else
- public override UIViewController PopViewControllerAnimated (bool animated)
- #endif
- {
- RemoveViewControllers(animated);
-#if __UNIFIED__
- return base.PopViewController(animated);
-#else
- return base.PopViewControllerAnimated (animated);
- #endif
- }
-
public Task<bool> PushPageAsync(Page page, bool animated = true)
{
return OnPushAsync(page, animated);
poppedViewController = base.PopViewController(animated);
#else
poppedViewController = base.PopViewControllerAnimated (animated);
- #endif
+#endif
if (poppedViewController == null)
{
// In the future we may want to make RemovePageAsync and deprecate RemovePage to handle cases where Push/Pop is called
// during a remove cycle.
+ var parentingVC = target as ParentingViewController;
+ if (parentingVC != null)
+ parentingVC.IgnorePageBeingRemoved = true;
if (_removeControllers == null)
{
UpdateLeftBarButtonItem(parentingViewController, page);
}
- void RemoveViewControllers(bool animated)
- {
- var controller = TopViewController as ParentingViewController;
- if (controller == null || controller.Child == null)
- return;
-
- // Gesture in progress, lets not be proactive and just wait for it to finish
- var count = ViewControllers.Length;
- var task = GetAppearedOrDisappearedTask(controller.Child);
- task.ContinueWith(async t =>
- {
- // task returns true if the user lets go of the page and is not popped
- // however at this point the renderer is already off the visual stack so we just need to update the NavigationPage
- // Also worth noting this task returns on the main thread
- if (t.Result)
- return;
- _ignorePopCall = true;
- // because iOS will just chain multiple animations together...
- var removed = count - ViewControllers.Length;
- for (var i = 0; i < removed; i++)
- {
- // lets just pop these suckers off, do not await, the true is there to make this fast
- await ((INavigationPageController)Element).PopAsyncInner(animated, true);
- }
- // because we skip the normal pop process we need to dispose ourselves
- controller.Dispose();
- _ignorePopCall = false;
- }, TaskScheduler.FromCurrentSynchronizationContext());
- }
-
void UpdateBackgroundColor()
{
var color = Element.BackgroundColor == Color.Default ? Color.White : Element.BackgroundColor;
}
}
+ public bool IgnorePageBeingRemoved
+ {
+ get;
+ set;
+ }
+
public event EventHandler Appearing;
public override void DidRotate(UIInterfaceOrientation fromInterfaceOrientation)
base.ViewWillAppear(animated);
}
+ public override async void DidMoveToParentViewController(UIViewController parent)
+ {
+ //If Parent of our child is already null we removed this using our API
+ //If we still have parent and we are removing our render we need to update our navigation
+ if (parent == null && !IgnorePageBeingRemoved)
+ {
+ NavigationRenderer n;
+ if (_navigation.TryGetTarget(out n))
+ {
+ var navController = n.Element as INavigationPageController;
+ await navController?.PopAsyncInner(true, true);
+ }
+
+ }
+ base.DidMoveToParentViewController(parent);
+
+ }
+
protected override void Dispose(bool disposing)
{
if (disposing)