【问题标题】:What's a consistent way to get the safe area insets for the iPhone X in Xamarin.Forms在 Xamarin.Forms 中获取 iPhone X 安全区域插图的一致方法是什么
【发布时间】:2017-12-05 06:08:50
【问题描述】:

我目前正在更新 iPhone X 的一些视图。根据this blog post 的说法,它应该是相当直截了当的,但是 - 像往常一样 - 它并不像预期的那样流畅。

如果你使用推荐的方式

public MyView()
{
    InitializeComponent();

    On<Xamarin.Forms.PlatformConfiguration.iOS>().SetUseSafeArea(true);
}

根据安全区域插图,视图的项目被赋予Margin,但这也适用于像SearchBar 这样的视图,它们已经适应了开箱即用的插图。使用上面的代码会导致搜索栏的灰色背景没有占据整个宽度,看起来很奇怪。

幸运的是,On&lt;iOS&gt; 有一个扩展方法 SafeAreaInsets(),它返回正确的插入 - 在某些条件下 - 例如可以分配给 BindableProperty。不幸的是,我们可以获得插图的条件不是很一致。

  • OnSizeAllocated第一次被调用时,SafeAreaInsets()会返回0,0,0,0
  • 当视图显示时SafeAreaInsets() 返回正确的值(在OnAppearing
  • OnSizeAllocated 旋转后称为乘法
    • SafeAreaInsets()第一次返回正确值
    • 第二次SafeAreaInsets()返回0,0,0,0

我当前的工作解决方案是,如果SafeAreaInsets() 返回的Thickness 不是default(Thickness),则覆盖两者并仅设置我的可绑定属性(绑定到我的视图)。

我想知道是否有一种标准方法可以始终获得正确的插图,而无需检查插图是否具有合理的价值。

【问题讨论】:

  • 你找到解决办法了吗?
  • 值得一提的是您使用的是哪个版本的 Xamarin.Forms,以防它是/曾经是错误。

标签: xamarin.forms iphone-x


【解决方案1】:

我对此做了一些研究。以下是我的一些想法:

  1. 您实际上可以在 XAML 中设置 UseSafeArea (docs) - 仅供参考

  2. SafeArea 的设置发生在使用this extension method 时,它基本上设置SafeAreaInsetsPropertyKey 属性,然后在UpdatePadding 方法中更新页面Padding。这里的问题是,什么调用该扩展方法并设置它呢?我检查了 Xamarin.Forms github repo,答案很简单。当ViewSafeAreaInsetsDidChangeiOS 调用时,它从PageRenderer 调用。这意味着您无法确切知道 iOS 何时决定通知您当前的 SafeArea - 您在不同时间使用不同的插图值看到的问题。

我知道这绝对不是任何人想要的,但您可以覆盖默认的 iOS PageRenderer 并连接到 ViewSafeAreaInsetsDidChange 覆盖。一旦调用它,您就可以 100% 确定您拥有当前的 SafeArea 插入值。

【讨论】:

  • 非常感谢您的回答,但这不是我需要的 100%。我更喜欢看我必须处理的边缘情况。
【解决方案2】:

我使用订阅更改了属性值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;
}

【讨论】:

    猜你喜欢
    • 2018-04-28
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-01-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多