Xamarin.Forms and Notch - Fri, Aug 23, 2019
Since the release of iPhone X, we have to deal with devices with notches and make sure our UI elements don’t overlap with the notifications bar, the notch and the task switching bar on the bottom of the screen. However, we can’t just add a fixed padding to everything to resolve this issue, because devices without notch and with smaller safe areas also exist, and we have to support them as well.
This leads to a lot of nasty spaghetti code which can be hard to maintain.
Fortunately, RedCorners.Forms
comes to rescue. It provides smart alternatives to ContentPage
and ContentView
that can automatically adjust their paddings based on the iOS device used. Simply derive your pages from RedCorners.Forms.ContentPage2
or your views from RedCorners.Forms.ContentView2
and set their FixTopPadding
and/or FixBottomPadding
properties to automatically adjust their paddings based on the device.
<rf:ContentPage2
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:rf="clr-namespace:RedCorners.Forms;assembly=RedCorners.Forms"
xmlns:vm="clr-namespace:Demos.ViewModels"
mc:Ignorable="d"
x:Class="Demos.Views.FixPaddingPage"
BackgroundColor="Black"
FixBottomPadding="{Binding FixBottomPadding}"
FixTopPadding="{Binding FixTopPadding}"
UIStatusBarStyle="{Binding UIStatusBarStyle}">
<ContentPage.BindingContext>
<vm:FixPaddingViewModel />
</ContentPage.BindingContext>
<Grid BackgroundColor="White">
<StackLayout HorizontalOptions="Fill" VerticalOptions="Center" Padding="30">
<Grid>
<Label Text="FixTopPadding" />
<Switch HorizontalOptions="End" IsToggled="{Binding FixTopPadding}" />
</Grid>
<Grid>
<Label Text="FixBottomPadding" />
<Switch HorizontalOptions="End" IsToggled="{Binding FixBottomPadding}" />
</Grid>
<Button Text="Close" Command="{Static rf:Values.PopCommand}" />
</StackLayout>
</Grid>
</rf:ContentPage2>
View Model:
public class FixPaddingViewModel : BindableModel
{
public UIStatusBarStyles UIStatusBarStyle =>
FixTopPadding ?
UIStatusBarStyles.LightContent :
UIStatusBarStyles.Default;
bool _fixTopPadding = false;
public bool FixTopPadding
{
get => _fixTopPadding;
set
{
SetProperty(ref _fixTopPadding, value);
RaisePropertyChanged(nameof(UIStatusBarStyle));
}
}
bool _fixBottomPadding = false;
public bool FixBottomPadding
{
get => _fixBottomPadding;
set => SetProperty(ref _fixBottomPadding, value);
}
}
In this example, we also change the UIStatusBarStyle
to make sure it is visible for any given FixTopPadding
value.