I am currently updating some views for the iPhone X. According to this blog post it should be fairly streight-forward, but - like always - it's not as smooth as it's supposed to be.
If you are using the recommended way
public MyView()
{
    InitializeComponent();
    On<Xamarin.Forms.PlatformConfiguration.iOS>().SetUseSafeArea(true);
}
the items of the View are given a Margin according to the safe area insets, but this applies to views like SearchBar, too, which already adapt to the insets out of the box. Using the code above will result in the gray background of the search bar not taking the whole width, which looks quite strange.
Fortunately the On<iOS> has an extension method SafeAreaInsets() which returns the correct insets - under certain conditions - which one for example can assign to a BindableProperty. Unfortunately the conditions under which we can obtain the insets are not very consistent. 
OnSizeAllocated is called the first time, SafeAreaInsets() will return 0,0,0,0
SafeAreaInsets() returns the correct value (in OnAppearing)OnSizeAllocated is called multiply after rotation
SafeAreaInsets() returns the correct valueSafeAreaInsets() returns 0,0,0,0
My current working solution is, to override both and only set my bindable property (which is bound to my views) if the Thickness returned by SafeAreaInsets() is not default(Thickness). 
I'd like to know if there is a standard way to always get the correct insets, without having to check if the insets have a sound value.
I did a bit of research on this. Here's couple of my thoughts:
You could actually set the UseSafeArea in XAML (docs) - that's just FYI
The setting of the SafeArea happens when using this extension method, which basically sets the SafeAreaInsetsPropertyKey property and then the page Padding is updated in the UpdatePadding method. The question here is, what calls that extension method and sets it then? I checked the Xamarin.Forms github repo and the answer is simple. It gets called from the PageRenderer, when the ViewSafeAreaInsetsDidChange is called by the iOS. Which means that you don't know exactly when iOS decides to inform you about the current SafeArea - the issues that you're seeing with different values of the inset at different times.
I know it's definitely not what anyone wants but you could override the default iOS PageRenderer and hook up to the ViewSafeAreaInsetsDidChange override. Once it's called you could be 100% sure that you have current SafeArea inset value. 
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With