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