[iOS] Change when we updated the XF INavigationPageController after popping a page...
authorRui Marinho <me@ruimarinho.net>
Tue, 16 Aug 2016 18:31:53 +0000 (19:31 +0100)
committerJason Smith <jason.smith@xamarin.com>
Tue, 16 Aug 2016 18:31:53 +0000 (11:31 -0700)
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39908.cs [new file with mode: 0644]
Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Xamarin.Forms.Controls.Issues.Shared.projitems
Xamarin.Forms.Core.Android.UITests/App.cs [deleted file]
Xamarin.Forms.Core.Android.UITests/Xamarin.Forms.Core.Android.UITests.csproj
Xamarin.Forms.Core.iOS.UITests/App.cs [deleted file]
Xamarin.Forms.Core.iOS.UITests/BaseTestFixture.cs
Xamarin.Forms.Core.iOS.UITests/Tests/Legacy-UnevenListTests.cs
Xamarin.Forms.Core.iOS.UITests/Xamarin.Forms.Core.iOS.UITests.csproj
Xamarin.Forms.Platform.iOS/Renderers/NavigationRenderer.cs

diff --git a/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39908.cs b/Xamarin.Forms.Controls.Issues/Xamarin.Forms.Controls.Issues.Shared/Bugzilla39908.cs
new file mode 100644 (file)
index 0000000..d9a620e
--- /dev/null
@@ -0,0 +1,72 @@
+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());
+               }
+       }
+}
index 6d35da9..1b4e0b8 100644 (file)
     <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">
diff --git a/Xamarin.Forms.Core.Android.UITests/App.cs b/Xamarin.Forms.Core.Android.UITests/App.cs
deleted file mode 100644 (file)
index 76c94d8..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-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
index 685c819..ee73cf8 100644 (file)
@@ -22,7 +22,7 @@
     <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' ">
@@ -57,9 +57,8 @@
     <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
diff --git a/Xamarin.Forms.Core.iOS.UITests/App.cs b/Xamarin.Forms.Core.iOS.UITests/App.cs
deleted file mode 100644 (file)
index dee82d8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-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
index c60ef35..b2f98e2 100644 (file)
@@ -16,22 +16,22 @@ namespace Xamarin.Forms.Core.UITests
        {
                // 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
                        {
@@ -50,43 +50,33 @@ namespace Xamarin.Forms.Core.UITests
 #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();
                }
        }
 }
index b425545..86a39ad 100644 (file)
@@ -21,10 +21,11 @@ namespace Xamarin.Forms.Core.UITests
                [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);
                        }
                }
 
index 3454e07..9c5ad1b 100644 (file)
@@ -22,7 +22,7 @@
     <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
index fcc3752..271291d 100644 (file)
@@ -109,33 +109,11 @@ namespace Xamarin.Forms.Platform.iOS
                        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);
@@ -330,7 +308,7 @@ namespace Xamarin.Forms.Platform.iOS
                        poppedViewController = base.PopViewController(animated);
 #else
                        poppedViewController = base.PopViewControllerAnimated (animated);
-                       #endif
+#endif
 
                        if (poppedViewController == null)
                        {
@@ -514,6 +492,9 @@ namespace Xamarin.Forms.Platform.iOS
 
                        // 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)
                        {
@@ -530,36 +511,6 @@ namespace Xamarin.Forms.Platform.iOS
                        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;
@@ -799,6 +750,12 @@ namespace Xamarin.Forms.Platform.iOS
                                }
                        }
 
+                       public bool IgnorePageBeingRemoved
+                       {
+                               get;
+                               set;
+                       }
+
                        public event EventHandler Appearing;
 
                        public override void DidRotate(UIInterfaceOrientation fromInterfaceOrientation)
@@ -853,6 +810,24 @@ namespace Xamarin.Forms.Platform.iOS
                                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)