我目前正在为iPhone X更新一些视图。根据this blog post,它应该是相当直接的,但是 - 像往常一样 - 它不像它应该的那么顺利是
如果您使用推荐的方式
public MyView()
{
InitializeComponent();
On<Xamarin.Forms.PlatformConfiguration.iOS>().SetUseSafeArea(true);
}
根据安全区域插入,视图的项目被赋予Margin
,但这也适用于SearchBar
之类的视图,它们已经适应了开箱即用的插图。使用上面的代码将导致搜索栏的灰色背景不占据整个宽度,这看起来很奇怪。
幸运的是On<iOS>
有一个扩展方法SafeAreaInsets()
,它返回正确的插入 - 在某些条件下 - 例如,哪一个可以分配给BindableProperty
。不幸的是,我们获得内容的条件并不十分一致。
OnSizeAllocated
时,SafeAreaInsets()
将返回0,0,0,0
SafeAreaInsets()
会返回正确的值(在OnAppearing
)OnSizeAllocated
在轮换后被称为multiply
SafeAreaInsets()
返回正确的值SafeAreaInsets()
返回0,0,0,0
我目前的工作解决方案是,如果Thickness
返回的SafeAreaInsets()
不是default(Thickness)
,则覆盖两者并仅设置我的可绑定属性(绑定到我的视图)。
我想知道是否有标准方法可以始终获得正确的插入内容,而无需检查插图是否具有声音值。
答案 0 :(得分:1)
我对此做了一些研究。这是我对此的几点看法:
您实际上可以在XAML(docs)中设置UseSafeArea
-就是说
使用this extension method时会发生SafeArea
的设置,该设置基本上是设置SafeAreaInsetsPropertyKey
属性,然后页面Padding
在{{1 }} 方法。这里的问题是,什么调用该扩展方法并进行设置?我检查了Xamarin.Forms github存储库,答案很简单。当ViewSafeAreaInsetsDidChange
调用iOS时,将从UpdatePadding
调用它。这意味着您不确切知道iOS何时决定通知您当前的PageRenderer
-您在不同的时间使用不同的插图值看到的问题。
我知道这绝对不是任何人想要的,但是您可以覆盖默认的iOS SafeArea
并使用PageRenderer
覆盖。调用后,您可以100%确保您具有当前的ViewSafeAreaInsetsDidChange
插入值。
答案 1 :(得分:0)
我使用订阅来更改属性值SafeAreaInsets
。这补充了OnSizeAllocated
的错误解决方案。
public bool WasAppeared { get; private set; }
public CustomContentPage() : base()
{
if (Device.RuntimePlatform == Device.iOS)
PropertyChanged += CustomContentPage_PropertyChanged;
}
protected override void OnAppearing()
{
base.OnAppearing();
WasAppeared = true;
SetSafeArea();
}
protected override void OnDisappearing()
{
WasAppeared = false;
base.OnDisappearing();
}
private void CustomContentPage_PropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
{
if (!WasAppeared)
return;
if (e.PropertyName == "SafeAreaInsets")
SetSafeArea();
}
protected void SetSafeArea()
{
if (Device.RuntimePlatform != Device.iOS)
return;
}