Skip to content
Original file line number Diff line number Diff line change
Expand Up @@ -925,4 +925,4 @@ public override bool CanScrollVertically()
}
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -325,41 +325,51 @@ void LayoutHeader(CGRect parentFrame)

void LayoutContent(CGRect parentBounds, nfloat footerHeight)
{
double contentYOffset = 0;
var safeAreaInsets = UIApplication.SharedApplication.GetSafeAreaInsetsForWindow();

if (ShouldHonorSafeArea(HeaderView?.View) ||
(HeaderView is null && ShouldHonorSafeArea(Content)))
// Honor ISafeAreaView.IgnoreSafeArea and explicit margins (same as LayoutHeader)
nfloat safeAreaTop = 0;
if (ShouldHonorSafeArea(HeaderView?.View) || (HeaderView is null && ShouldHonorSafeArea(Content)))
{
// We add the safe area if margin is not explicitly set. This matches the header behavior.
contentYOffset += (float)UIApplication.SharedApplication.GetSafeAreaInsetsForWindow().Top;
safeAreaTop = safeAreaInsets.Top;
}
nfloat safeAreaBottom = safeAreaInsets.Bottom;

var contentY = parentBounds.Y + safeAreaTop;
var contentHeight = parentBounds.Height - safeAreaTop - safeAreaBottom - footerHeight;

if (HeaderView is not null)
{
if (ScrollView is null)
{
// The margin is already managed by MAUI's layout system, so we don't need to add it here and we just offset the content by the header's height.
contentYOffset += HeaderView.Frame.Height;
// The margin is already managed by MAUI's layout system, so we don't need to add it here
// and we just offset the content by the header's height.
contentY += HeaderView.Frame.Height;
contentHeight -= HeaderView.Frame.Height;
}
else
{
var headerBehavior = _context.Shell.FlyoutHeaderBehavior;
if (headerBehavior == FlyoutHeaderBehavior.Default || headerBehavior == FlyoutHeaderBehavior.Fixed)
{
// For Default/Fixed, position the scroll view below the header so items
// cannot scroll behind it. No content inset is needed in this case.
contentYOffset += HeaderView.Frame.Height;
// For Default/Fixed, the scroll view frame is positioned below the header so items
// cannot scroll behind it. SetHeaderContentInset sets no top content inset here.
contentY += HeaderView.Frame.Height;
contentHeight -= HeaderView.Frame.Height;
}
else
{
// For Scroll/CollapseOnScroll, the scroll view overlaps the header so the header
// can scroll away or shrink. The content inset is managed by SetHeaderContentInset.
contentYOffset += HeaderView.View.Margin.VerticalThickness;
// can scroll away or shrink. The content inset is managed by SetHeaderContentInset;
// only account for margin here.
var marginOffset = (nfloat)HeaderView.View.Margin.VerticalThickness;
contentY += marginOffset;
contentHeight -= marginOffset;
}
}
}

var contentFrame = new Rect(parentBounds.X, contentYOffset, parentBounds.Width, parentBounds.Height - contentYOffset - footerHeight);
var contentFrame = new Rect(parentBounds.X, contentY, parentBounds.Width, contentHeight);
if (Content is null)
{
ContentView.Frame = contentFrame.AsCGRect();
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,3 @@
#if ANDROID //More info : https://github.com/dotnet/maui/pull/33335
using NUnit.Framework;
using UITest.Appium;
using UITest.Core;
Expand All @@ -7,8 +6,6 @@ namespace Microsoft.Maui.TestCases.Tests.Issues;

public class Issue32275 : _IssuesUITest
{
const string FlyoutItem = "FlyoutItem";
const string ResetButton = "Reset";
public override string Issue => "Shell Flyout SafeArea Rendering";

protected override bool ResetAfterEachTest => true;
Expand All @@ -34,8 +31,8 @@ public void VerifyFlyoutWithHeaderFooter()
App.Tap("ToggleHeaderFooter");
App.WaitForElement("PageLoaded");
App.ShowFlyout();
App.WaitForElement("Header");
App.WaitForElement("Footer");
App.WaitForElement("Header View");
App.WaitForElement("Footer View");
VerifyScreenshot();
}

Expand All @@ -62,8 +59,8 @@ public void VerifyCustomFlyoutContentTemplateWithHeaderFooter()
App.Tap("ToggleHeaderFooter");
App.WaitForElement("PageLoaded");
App.ShowFlyout();
App.WaitForElement("Header");
App.WaitForElement("Footer");
App.WaitForElement("Header View");
App.WaitForElement("Footer View");
VerifyScreenshot();
}

Expand Down Expand Up @@ -92,9 +89,8 @@ public void VerifyCustomFlyoutContentWithHeaderFooter()
App.WaitForElement("PageLoaded");
App.ShowFlyout();
App.WaitForElement("ContentView");
App.WaitForElement("Header");
App.WaitForElement("Footer");
App.WaitForElement("Header View");
App.WaitForElement("Footer View");
VerifyScreenshot();
}
}
#endif
}
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading