Only set the Page Padding via SafeAreaInset on iOS (#3811)

* only set the Page Padding via SafeAreaInset on iOS
-fixes #3809

* [Controls] add waits for clicks in ui tests

* [Controls] remove wrong category

* [iOS] Move inset logic down into ios renderer
This commit is contained in:
Shane Neuville 2018-10-02 01:43:53 -06:00 коммит произвёл Stephane Delcroix
Родитель 379adeb380
Коммит 4c367911b9
4 изменённых файлов: 158 добавлений и 25 удалений

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

@ -0,0 +1,129 @@
using System.Linq;
using Xamarin.Forms.CustomAttributes;
using Xamarin.Forms.Internals;
using Xamarin.Forms.PlatformConfiguration.iOSSpecific;
#if UITEST
using Xamarin.UITest;
using NUnit.Framework;
using Xamarin.Forms.Core.UITests;
#endif
namespace Xamarin.Forms.Controls.Issues
{
[Preserve(AllMembers = true)]
[Issue(IssueTracker.Github, 3809, "SetUseSafeArea is wiping out Page Padding ")]
public class Issue3809 : TestMasterDetailPage
{
const string _setPagePadding = "Set Page Padding";
const string _safeAreaText = "Safe Area Enabled: ";
const string _paddingLabel = "paddingLabel";
const string _safeAreaAutomationId = "SafeAreaAutomation";
Label label = null;
protected override void Init()
{
label = new Label()
{
AutomationId = _paddingLabel
};
Master = new ContentPage() { Title = "Master" };
Button button = null;
button = new Button()
{
Text = $"{_safeAreaText}{true}",
AutomationId = _safeAreaAutomationId,
Command = new Command(() =>
{
bool safeArea = !Detail.On<PlatformConfiguration.iOS>().UsingSafeArea();
Detail.On<PlatformConfiguration.iOS>().SetUseSafeArea(safeArea);
button.Text = $"{_safeAreaText}{safeArea}";
Device.BeginInvokeOnMainThread(() => label.Text = $"{Detail.Padding.Left}, {Detail.Padding.Top}, {Detail.Padding.Right}, {Detail.Padding.Bottom}");
})
};
Detail = new ContentPage()
{
Title = "Details",
Content = new StackLayout()
{
Children =
{
new ListView(ListViewCachingStrategy.RecycleElement)
{
ItemsSource = Enumerable.Range(0,200).Select(x=> x.ToString()).ToList()
},
label,
button,
new Button()
{
Text = _setPagePadding,
Command = new Command(() =>
{
Detail.Padding = new Thickness(25, 25, 25, 25);
Device.BeginInvokeOnMainThread(() => label.Text = $"{Detail.Padding.Left}, {Detail.Padding.Top}, {Detail.Padding.Right}, {Detail.Padding.Bottom}");
})
}
}
}
};
Detail.Padding = new Thickness(25, 25, 25, 25);
Detail.On<Xamarin.Forms.PlatformConfiguration.iOS>().SetUseSafeArea(true);
}
protected override void OnAppearing()
{
base.OnAppearing();
label.Text = $"{Detail.Padding.Left}, {Detail.Padding.Top}, {Detail.Padding.Right}, {Detail.Padding.Bottom}";
}
#if UITEST
[Test]
public void SafeAreaInsetsBreaksAndroidPadding()
{
// ensure initial paddings are honored
RunningApp.WaitForElement($"{_safeAreaText}{true}");
var element = RunningApp.WaitForElement(_paddingLabel).First();
bool usesSafeAreaInsets = false;
if (element.Text != "25, 25, 25, 25")
usesSafeAreaInsets = true;
Assert.AreNotEqual(element.Text, "0, 0, 0, 0");
if (!usesSafeAreaInsets)
Assert.AreEqual(element.Text, "25, 25, 25, 25");
// disable Safe Area Insets
RunningApp.Tap(_safeAreaAutomationId);
RunningApp.WaitForElement($"{_safeAreaText}{false}");
element = RunningApp.WaitForElement(_paddingLabel).First();
if (usesSafeAreaInsets)
Assert.AreEqual(element.Text, "0, 0, 0, 0");
else
Assert.AreEqual(element.Text, "25, 25, 25, 25");
// enable Safe Area insets
RunningApp.Tap(_safeAreaAutomationId);
RunningApp.WaitForElement($"{_safeAreaText}{true}");
element = RunningApp.WaitForElement(_paddingLabel).First();
Assert.AreNotEqual(element.Text, "0, 0, 0, 0");
if (!usesSafeAreaInsets)
Assert.AreEqual(element.Text, "25, 25, 25, 25");
// Set Padding and then disable safe area insets
RunningApp.Tap(_setPagePadding);
RunningApp.Tap(_safeAreaAutomationId);
RunningApp.WaitForElement($"{_safeAreaText}{false}");
element = RunningApp.WaitForElement(_paddingLabel).First();
Assert.AreEqual(element.Text, "25, 25, 25, 25");
}
#endif
}
}

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

@ -9,6 +9,7 @@
<Import_RootNamespace>Xamarin.Forms.Controls.Issues</Import_RootNamespace>
</PropertyGroup>
<ItemGroup>
<Compile Include="$(MSBuildThisFileDirectory)Issue3809.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue2894.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue3524.cs" />
<Compile Include="$(MSBuildThisFileDirectory)Issue2004.cs" />

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

@ -58,18 +58,7 @@
return config;
}
public static readonly BindableProperty UseSafeAreaProperty = BindableProperty.Create("UseSafeArea", typeof(bool), typeof(Page), false, propertyChanged: (bindable, oldValue, newValue) =>
{
var page = bindable as Xamarin.Forms.Page;
if ((bool)oldValue && !(bool)newValue)
{
page.Padding = default(Thickness);
}
else
{
UpdatePadding(GetSafeAreaInsets(page), page);
}
});
public static readonly BindableProperty UseSafeAreaProperty = BindableProperty.Create("UseSafeArea", typeof(bool), typeof(Page), false);
public static bool GetUseSafeArea(BindableObject element)
{
@ -115,17 +104,7 @@
return config;
}
static readonly BindablePropertyKey SafeAreaInsetsPropertyKey = BindableProperty.CreateReadOnly(nameof(SafeAreaInsets), typeof(Thickness), typeof(Page), default(Thickness), propertyChanged: (bindable, oldValue, newValue) =>
{
var page = bindable as Xamarin.Forms.Page;
UpdatePadding((Thickness)newValue, page);
});
static void UpdatePadding(Thickness thickness, FormsElement page)
{
if (page.On<iOS>().UsingSafeArea())
page.Padding = thickness;
}
static readonly BindablePropertyKey SafeAreaInsetsPropertyKey = BindableProperty.CreateReadOnly(nameof(SafeAreaInsets), typeof(Thickness), typeof(Page), default(Thickness));
public static readonly BindableProperty SafeAreaInsetsProperty = SafeAreaInsetsPropertyKey.BindableProperty;

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

@ -18,6 +18,9 @@ namespace Xamarin.Forms.Platform.iOS
Page Page => Element as Page;
bool UsingSafeArea => (Forms.IsiOS11OrNewer) ? Page.On<PlatformConfiguration.iOS>().UsingSafeArea() : false;
Thickness SafeAreaInsets => Page.On<PlatformConfiguration.iOS>().SafeAreaInsets();
public PageRenderer()
{
}
@ -70,13 +73,14 @@ namespace Xamarin.Forms.Platform.iOS
if (page != null && Forms.IsiOS11OrNewer)
{
var insets = NativeView.SafeAreaInsets;
if(page.Parent is TabbedPage)
if (page.Parent is TabbedPage)
{
insets.Bottom = 0;
}
page.On<PlatformConfiguration.iOS>().SetSafeAreaInsets(new Thickness(insets.Left, insets.Top, insets.Right, insets.Bottom));
}
base.ViewSafeAreaInsetsDidChange();
}
@ -195,6 +199,10 @@ namespace Xamarin.Forms.Platform.iOS
UpdateTitle();
else if (e.PropertyName == PlatformConfiguration.iOSSpecific.Page.PrefersStatusBarHiddenProperty.PropertyName)
UpdateStatusBarPrefersHidden();
else if (Forms.IsiOS11OrNewer && e.PropertyName == PlatformConfiguration.iOSSpecific.Page.UseSafeAreaProperty.PropertyName)
UpdateUseSafeArea();
else if (Forms.IsiOS11OrNewer && e.PropertyName == PlatformConfiguration.iOSSpecific.Page.SafeAreaInsetsProperty.PropertyName)
UpdateUseSafeArea();
}
public override UIKit.UIStatusBarAnimation PreferredStatusBarUpdateAnimation
@ -215,6 +223,22 @@ namespace Xamarin.Forms.Platform.iOS
}
}
void UpdateUseSafeArea()
{
if (!Forms.IsiOS11OrNewer) return;
if (!UsingSafeArea)
{
var safeAreaInsets = SafeAreaInsets;
if (safeAreaInsets == Page.Padding)
Page.Padding = default(Thickness);
}
else
{
Page.Padding = SafeAreaInsets;
}
}
void UpdateStatusBarPrefersHidden()
{
if (Element == null)