diff --git a/src/Controls/tests/TestCases.HostApp/Issues/Issue33458.cs b/src/Controls/tests/TestCases.HostApp/Issues/Issue33458.cs new file mode 100644 index 000000000000..167d03bef7ca --- /dev/null +++ b/src/Controls/tests/TestCases.HostApp/Issues/Issue33458.cs @@ -0,0 +1,42 @@ +namespace Maui.Controls.Sample.Issues; + +[Issue(IssueTracker.Github, 33458, "SafeArea incorrectly applied when using ControlTemplate with ContentPresenter", PlatformAffected.iOS)] +public class Issue33458 : TestContentPage +{ + protected override void Init() + { + AutomationId = "TestPage"; + SafeAreaEdges = SafeAreaEdges.None; + ControlTemplate = new ControlTemplate(() => new ContentPresenter()); + + var stackLayout = new VerticalStackLayout + { + AutomationId = "TestStackLayout", + Padding = new Thickness(30, 0), + Spacing = 25, + BackgroundColor = Colors.Green, + SafeAreaEdges = SafeAreaEdges.None, + Children = + { + new Image + { + AutomationId = "BotImage", + Source = "dotnet_bot.png", + HeightRequest = 185, + Aspect = Aspect.AspectFit + }, + new Label { AutomationId = "HelloLabel", Text = "Hello, World!" }, + new Label { AutomationId = "WelcomeLabel", Text = "Welcome to\n.NET Multi-platform App UI" }, + new Button { AutomationId = "CounterBtn", Text = "Click me", HorizontalOptions = LayoutOptions.Fill } + } + }; + + Content = new ScrollView + { + AutomationId = "TestScrollView", + BackgroundColor = Colors.Red, + SafeAreaEdges = SafeAreaEdges.None, + Content = stackLayout + }; + } +} diff --git a/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33458.cs b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33458.cs new file mode 100644 index 000000000000..a4222946cae9 --- /dev/null +++ b/src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33458.cs @@ -0,0 +1,29 @@ +#if IOS || ANDROID +using NUnit.Framework; +using UITest.Appium; +using UITest.Core; + +namespace Microsoft.Maui.TestCases.Tests.Issues; + +public class Issue33458 : _IssuesUITest +{ + public override string Issue => "SafeArea incorrectly applied when using ControlTemplate with ContentPresenter"; + + public Issue33458(TestDevice device) : base(device) { } + + [Test] + [Category(UITestCategories.SafeAreaEdges)] + public void ScrollViewSafeAreaWorksWithControlTemplate() + { + var pageRect = App.WaitForElement("TestPage").GetRect(); + var scrollViewRect = App.WaitForElement("TestScrollView").GetRect(); + + // ContentPresenter should not apply safe area - ScrollView should match page bounds + Assert.That(scrollViewRect.Y, Is.EqualTo(pageRect.Y), + "ScrollView Y should match Page Y - no top inset from ContentPresenter"); + + Assert.That(scrollViewRect.Height, Is.EqualTo(pageRect.Height), + $"ScrollView height should match Page height - no insets from ContentPresenter. Expected: {pageRect.Height}, Actual: {scrollViewRect.Height}"); + } +} +#endif diff --git a/src/Core/src/Platform/iOS/MauiView.cs b/src/Core/src/Platform/iOS/MauiView.cs index 2e47eb0da8a2..06df6c168c19 100644 --- a/src/Core/src/Platform/iOS/MauiView.cs +++ b/src/Core/src/Platform/iOS/MauiView.cs @@ -357,13 +357,14 @@ SafeAreaPadding GetAdjustedSafeAreaInsets() return new SafeAreaPadding(left, right, top, bottom); } - // Fallback to legacy behavior - if (View is ISafeAreaView sav && sav.IgnoreSafeArea) + // Fallback to legacy ISafeAreaView behavior + if (View is ISafeAreaView sav) { - return SafeAreaPadding.Empty; + return sav.IgnoreSafeArea ? SafeAreaPadding.Empty : baseSafeArea; } - return baseSafeArea; + // Non-safe-area views pass through to parent + return SafeAreaPadding.Empty; } ///