SH L
SH L

Reputation: 31

.NET MAUI, ios UseSafeArea not working StackLayout, VerticalStackLayout and Grid

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft.com/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="Test.Views.Activities.ActivityMapList"
             xmlns:maps="clr-namespace:Microsoft.Maui.Controls.Maps;assembly=Microsoft.Maui.Controls.Maps"
             xmlns:sensors="clr-namespace:Microsoft.Maui.Devices.Sensors;assembly=Microsoft.Maui.Essentials"
             xmlns:ios="clr-namespace:Microsoft.Maui.Controls.PlatformConfiguration.iOSSpecific;assembly=Microsoft.Maui.Controls"
             ios:Page.UseSafeArea="False"
             Shell.NavBarIsVisible="False"
             Style="{StaticResource Key=DefaultPage}">
    <ContentPage.Content>
        <StackLayout>
            <maps:Map
                VerticalOptions="FillAndExpand"
                HorizontalOptions="FillAndExpand">
                <x:Arguments>
                    <MapSpan>
                        <x:Arguments>
                            <sensors:Location>
                                <x:Arguments>
                                    <x:Double>36.9628066</x:Double>
                                    <x:Double>-122.0194722</x:Double>
                                </x:Arguments>
                            </sensors:Location>
                            <x:Double>0.01</x:Double>
                            <x:Double>0.01</x:Double>
                        </x:Arguments>
                    </MapSpan>
                </x:Arguments>
            </maps:Map>
        </StackLayout>
    </ContentPage.Content>
</ContentPage>

enter image description here

Map Controls inside StackLayout or Grid, iOS's SafeArea is false as shown in the image. Do you have any solution?

enter image description here

I need with grid or stacklayout on map

Upvotes: 3

Views: 5907

Answers (4)

Lorenzo Melato
Lorenzo Melato

Reputation: 1636

My two cents. We are @18.01.2025, i'm trying out MAUI .NET 9 version.

It seems sufficient to use IgnoreSafeArea="True" in the Grid or in other layouts to overwrite the Safe areas.

Upvotes: 1

galex
galex

Reputation: 146

Add this handler into your MauiProgram. Tested for Maui .net8

#if IOS
        LayoutHandler.Mapper.AppendToMapping("Custom", (h, v) =>
        {
            if (v is Layout layout)
            {
                layout.IgnoreSafeArea = true;
            }
        });
#endif

Upvotes: 3

Liqun Shen-MSFT
Liqun Shen-MSFT

Reputation: 8220

You could set the Page Padding value to make it. In the OnAppearing Method, set the safeInsets of the page like the following code:

protected override void OnAppearing()
{
    base.OnAppearing();
    
    DeviceSafeInsetsService d = new DeviceSafeInsetsService(); 
    double topArea = d.GetSafeAreaTop();
    double bottomArea = d.GetSafeAreaBottom();
    var safeInsets = On<iOS>().SafeAreaInsets();
    safeInsets.Top = -topArea;
    safeInsets.Bottom = -bottomArea;

    Padding = safeInsets;
}

To get the topArea and bottomArea value, you should write platform code. A more detailed tutorial about this is attached at the end of the answer.

First you could generate a new class file in Project folder and change it to partial class. Generate two partial method.

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

And then 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. When you generate this file, please remove the .Platforms.iOS suffix in the namespace.

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;
    }
}

For more information, you could refer to How To Write Platform-Specific Code in .NET MAUI and MauiPlatformCodeSample code

Hope it works for you.

Upvotes: 5

Kramer
Kramer

Reputation: 461

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: https://github.com/dotnet/maui/issues/5856

There's also a 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 your problem you need to add IgnoreSafeArea="True" to your Grid or StackLayout and ios:Page.UseSafeArea="False" to your page. This should not be necessary, but is a workaround that works for me.

iOS emulator showing content outside safe area

Documentation about disabling safe area 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

Upvotes: 15

Related Questions