Set safe areas for iOS in MAUI

ios safe areas

When you create an application for iOS in MAUI, we have to set the safe areas if we want to use the full screen for your application. The safe areas in iOS are one at the top and one at the bottom.

Where are the safe areas? - Set safe area for iOS in MAUI

At the top of the screen, you have the clock and other common system information plus the notch in the newest models. At the bottom of the screen, you have the home bar.

Issues

By default, .NET MAUI will take the safe area into account. So the use of the platform-specific UseSafeArea is to disable safe areas. Currently, setting UseSafeArea to false doesn’t change the behaviour (although it should), which is a bug. Also, see the issue on the MAUI Github.

There’s also an IgnoreSafeArea property you can set to achieve the same thing. However, it’s no longer working in .NET 7, see the following issue: https://github.com/dotnet/maui/issues/12823

To fix the problem you need to add IgnoreSafeArea="True" to your Grid or StackLayout and ios:Page.UseSafeArea="False" to your page.

Documentation about disabling safe areas on iOS can be found here: https://learn.microsoft.com/en-us/dotnet/maui/ios/platform-specifics/page-safe-area-layout?view=net-maui-7.0

Unfortunately, this is not enough to use the safe areas.

Solution

After spending a few hours, I think the best solution is to write a platform-specific code. First, I have to create a new class in the root of the project that I’m going to call DeviceSafeInsetsService

namespace LanguageInUse
{
    public partial class DeviceSafeInsetsService
    {
        public partial double GetSafeAreaTop();
        public partial double GetSafeAreaBottom();
    }
}

In the code above, I included the namespace for a reason. When I will implement the platform-specific code, the implementation must be in the same namespace. If not, it won’t work. Another important thing is that when you create without implementation, you get some errors like

Error CS8795 Partial method ‘DeviceSafeInsetsService.GetSafeAreaTop()’ must have an implementation part because it has accessibility modifiers. LanguageInUse (net8.0-windows10.0.19041.0) C:\Projects\ERDevOps\LIUApp\LanguageInUse\DeviceSafeInsetsService.cs 11 Active

This is normal. You have to implement this class in every platform. So, in the Windows and Android platforms (if you have your project also for Tizen and macCatalyst do it the same there), add a new class DeviceSafeInsetsService and just return a random value

namespace LanguageInUse
{
    public partial class DeviceSafeInsetsService
    {
        public partial double GetSafeAreaBottom()
        {
            return 0;
        }

        public partial double GetSafeAreaTop()
        {
            return 0;
        }
    }
}

iOS implementation

Now, generate a partial file on Platform iOS and implement it. This file is placed in the Project/Platform/iOS folder and what I want to mention is this file is a partial file, so the namespace should be the same as the file above.

namespace LanguageInUse
{
    public partial class DeviceSafeInsetsService
    {
        public partial double GetSafeAreaBottom()
        {
            if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
            {
                UIWindow window = UIApplication.SharedApplication.Delegate.GetWindow();
                var bottomPadding = window.SafeAreaInsets.Bottom;
                return bottomPadding;
            }
            return 0;
        }

        public partial double GetSafeAreaTop()
        {
            if (UIDevice.CurrentDevice.CheckSystemVersion(11, 0))
            {
                UIWindow window = UIApplication.SharedApplication.Delegate.GetWindow();
                var TopPadding = window.SafeAreaInsets.Top;
                return TopPadding;
            }
            return 0;
        }
    }
}

How to use it

Now, using the code above will force you to update your pages and probably add more namespace to avoid ambiguities. First, in the code behind for each page, add at the top this code to include the specific package for iOS.

#if IOS
using Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;
#endif

If for example in your code you have some reference to particular components like for example Application or ListView, you have to specify the right namespace. So, for example:

  • Application becomes Microsoft.Maui.Controls.Application
  • ListView becomes Microsoft.Maui.Controls.ListView

After that, you have to add the Padding in the OnAppearing function like here

protected override async void OnAppearing()
{
    base.OnAppearing();

    DeviceSafeInsetsService d = new DeviceSafeInsetsService();
    double topArea = d.GetSafeAreaTop();
    double bottomArea = d.GetSafeAreaBottom();

#if IOS
    var safeInsets = On<iOS>().SafeAreaInsets();
    safeInsets.Bottom = -bottomArea;
    safeInsets.Top = -topArea;

    Padding = safeInsets;
#endif
    }
}

Run and your app is using the full screen.

Wrap up

In conclusion, in this post, I show you how to set the safe areas for iOS in MAUI and NET8. I hope you find this code useful. If you have any questions or comments, please use the forum.

Leave a Reply

This site uses Akismet to reduce spam. Learn how your comment data is processed.