Fix RTL behavior for MasterDetailsPage when running on iOS 13 iPads (#7271)

* Fix RTL on iOS 13 tablets with MDP

* - add backgrounding extension for iOS
fixes #7224
fixes #7266
This commit is contained in:
Shane Neuville 2019-09-04 18:28:24 -06:00 коммит произвёл Samantha Houts
Родитель 5b6d7a2b14
Коммит 60bda80da6
5 изменённых файлов: 150 добавлений и 13 удалений

Просмотреть файл

@ -1,21 +1,41 @@
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
using System;
#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
#endif
namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 2818, "Right-to-Left MasterDetail in Xamarin.Forms Hamburger icon issue", PlatformAffected.Android)]
public class Issue2818 : MasterDetailPage
public class Issue2818 : TestMasterDetailPage
{
public Issue2818()
protected override void Init()
{
FlowDirection = FlowDirection.RightToLeft;
Master = new ContentPage
{
Title = "Master",
BackgroundColor = Color.SkyBlue,
IconImageSource = "menuIcon"
IconImageSource = "menuIcon",
Content = new StackLayout()
{
Children =
{
new Button()
{
Text = "If you can see me the test has passed",
AutomationId = "CloseMasterView",
Command = new Command(() => IsPresented = false)
}
},
AutomationId = "MasterLayout"
},
Padding = new Thickness(0, 42, 0, 0)
};
Detail = new NavigationPage(new ContentPage
@ -26,21 +46,92 @@ namespace Xamarin.Forms.Controls.Issues
Children = {
new Label
{
Text = "The page must be with RightToLeft FlowDirection. Hamburger icon in main page must be going to right side."
Text = "The page must be with RightToLeft FlowDirection. Hamburger icon in main page must be going to right side. There should be visible text inside the Master View"
},
new Button
{
Text = "Set RightToLeft",
Command = new Command(() => FlowDirection = FlowDirection.RightToLeft)
Command = new Command(() => FlowDirection = FlowDirection.RightToLeft),
AutomationId = "ShowRightToLeft"
},
new Button
{
Text = "Set LeftToRight",
Command = new Command(() => FlowDirection = FlowDirection.LeftToRight)
Command = new Command(() => FlowDirection = FlowDirection.LeftToRight),
AutomationId = "ShowLeftToRight"
},
new Button
{
Text = "Open Master View",
Command = new Command(() => IsPresented = true),
AutomationId = "OpenMasterView"
},
new Label()
{
Text = Device.Idiom.ToString(),
AutomationId = "Idiom"
}
}
}
});
}
#if UITEST
[Test]
public void MasterViewMovesAndContentIsVisible()
{
var idiom = RunningApp.WaitForElement("Idiom");
// This behavior is currently broken on a phone device Issue 7270
if (idiom[0].ReadText() != "Tablet")
return;
RunningApp.Tap("OpenMasterView");
RunningApp.Tap("CloseMasterView");
RunningApp.SetOrientationLandscape();
RunningApp.Tap("OpenMasterView");
var positionStart = RunningApp.WaitForElement("CloseMasterView");
RunningApp.Tap("ShowLeftToRight");
var results = RunningApp.QueryUntilPresent(() =>
{
var secondPosition = RunningApp.Query("CloseMasterView");
if (secondPosition.Length == 0)
return null;
if (secondPosition[0].Rect.X < positionStart[0].Rect.X)
return secondPosition;
return null;
});
Assert.IsNotNull(results, "Master View Did not change flow direction correctly");
Assert.AreEqual(1, results.Length, "Master View Did not change flow direction correctly");
}
#if __IOS__
[Test]
public void MasterViewSizeDoesntChangeAfterBackground()
{
var idiom = RunningApp.WaitForElement("Idiom");
// This behavior is currently broken on a phone device Issue 7270
if (idiom[0].ReadText() != "Tablet")
return;
RunningApp.SetOrientationLandscape();
RunningApp.Tap("CloseMasterView");
RunningApp.Tap("ShowLeftToRight");
var windowSize = RunningApp.WaitForElement("MasterLayout")[0];
RunningApp.SendAppToBackground(TimeSpan.FromSeconds(5));
var newWindowSize = RunningApp.WaitForElement("MasterLayout")[0];
Assert.AreEqual(newWindowSize.Rect.Width, windowSize.Rect.Width);
Assert.AreEqual(newWindowSize.Rect.Height, windowSize.Rect.Height);
}
#endif
#endif
}
}

Просмотреть файл

@ -4,6 +4,10 @@ using System.IO;
using Xamarin.UITest;
using Xamarin.UITest.Queries;
#if __IOS__
using Xamarin.UITest.iOS;
#endif
namespace Xamarin.Forms.Controls
{
/// <summary>
@ -445,6 +449,16 @@ namespace Xamarin.Forms.Controls
{
get { return _app.TestServer; }
}
#if __IOS__
public void SendAppToBackground(TimeSpan timeSpan)
{
if (_app is iOSApp app)
{
app.SendAppToBackground(timeSpan);
}
}
#endif
}
}
#endif

Просмотреть файл

@ -5,6 +5,9 @@ using Xamarin.UITest;
using Xamarin.UITest.Queries;
using System.Text.RegularExpressions;
using System.Threading;
#if __IOS__
using Xamarin.UITest.iOS;
#endif
namespace Xamarin.UITest
{
@ -28,6 +31,17 @@ namespace Xamarin.UITest
return results;
}
#if __IOS__
public static void SendAppToBackground(this IApp app, TimeSpan timeSpan)
{
if(app is Xamarin.Forms.Controls.ScreenshotConditionalApp sca)
{
sca.SendAppToBackground(timeSpan);
Thread.Sleep(timeSpan.Add(TimeSpan.FromSeconds(2)));
}
}
#endif
}
}

Просмотреть файл

@ -18,16 +18,25 @@ namespace Xamarin.Forms.Platform.iOS
}
}
internal static void UpdateFlowDirection(this UIView view, IVisualElementController controller)
internal static bool UpdateFlowDirection(this UIView view, IVisualElementController controller)
{
if (controller == null || view == null || !Forms.IsiOS9OrNewer)
return;
return false;
UISemanticContentAttribute updateValue = view.SemanticContentAttribute;
if (controller.EffectiveFlowDirection.IsRightToLeft())
view.SemanticContentAttribute = UISemanticContentAttribute.ForceRightToLeft;
updateValue = UISemanticContentAttribute.ForceRightToLeft;
else if (controller.EffectiveFlowDirection.IsLeftToRight())
view.SemanticContentAttribute = UISemanticContentAttribute.ForceLeftToRight;
updateValue = UISemanticContentAttribute.ForceLeftToRight;
if(updateValue != view.SemanticContentAttribute)
{
view.SemanticContentAttribute = updateValue;
return true;
}
return false;
}
internal static void UpdateTextAlignment(this UITextField control, IVisualElementController controller)

Просмотреть файл

@ -195,7 +195,11 @@ namespace Xamarin.Forms.Platform.iOS
if (layoutMaster)
{
var masterBounds = _masterController.View.Frame;
_masterWidth = (nfloat)Math.Max(_masterWidth, masterBounds.Width);
if (Forms.IsiOS13OrNewer)
_masterWidth = masterBounds.Width;
else
_masterWidth = (nfloat)Math.Max(_masterWidth, masterBounds.Width);
if (!masterBounds.IsEmpty)
MasterDetailPage.MasterBounds = new Rectangle(0, 0, _masterWidth, masterBounds.Height);
@ -385,7 +389,12 @@ namespace Xamarin.Forms.Platform.iOS
void UpdateFlowDirection()
{
NativeView.UpdateFlowDirection(Element);
if(NativeView.UpdateFlowDirection(Element) && Forms.IsiOS13OrNewer && NativeView.Superview != null)
{
var view = NativeView.Superview;
NativeView.RemoveFromSuperview();
view.AddSubview(NativeView);
}
}
class InnerDelegate : UISplitViewControllerDelegate