[iOS] Shell: Account for SafeArea when positioning flyout footer#32891
[iOS] Shell: Account for SafeArea when positioning flyout footer#32891PureWeen merged 3 commits intodotnet:inflight/currentfrom
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes an iOS-specific bug where Shell flyout footers with horizontal StackLayout were positioned below the visible area due to not accounting for the bottom safe area insets. The fix subtracts View.SafeAreaInsets.Bottom from the Y position calculation, and re-enables the previously commented-out horizontal orientation in the test case that was blocked by this issue.
Key changes:
- Corrects footer Y position calculation to account for bottom safe area insets on iOS
- Re-enables horizontal orientation test case that was previously disabled due to this bug
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated 1 comment.
| File | Description |
|---|---|
| src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutContentRenderer.cs | Updated UpdateFooterPosition() to subtract View.SafeAreaInsets.Bottom from footer Y coordinate |
| src/Controls/tests/TestCases.HostApp/Issues/XFIssue/HeaderFooterShellFlyout.cs | Removed comment and re-enabled Orientation = StackOrientation.Horizontal for flyout footer test |
| FlyoutFooter = new StackLayout() | ||
| { | ||
| // Problem with footer rendering when orientation is configured on iOS. Related issue: https://github.com/dotnet/maui/issues/26395 | ||
| // Orientation = StackOrientation.Horizontal, | ||
| Orientation = StackOrientation.Horizontal, | ||
| Children = { | ||
| new Label() { Text = "Footer" } | ||
| }, |
There was a problem hiding this comment.
The existing test should be enhanced to verify that the footer is positioned correctly within the safe area bounds on iOS. Currently, the test only verifies that the footer is visible after toggling, but doesn't validate its Y position accounting for SafeAreaInsets.Bottom.
Consider adding an iOS-specific test that:
- Toggles the horizontal footer (which now works with this fix)
- Verifies the footer's Y position is within the visible safe area
- Ensures the footer isn't rendered below
View.Frame.Height - SafeAreaInsets.Bottom
This would provide regression protection for the issue #26395 fix.
|
/rebase |
3af8b79 to
d928c6e
Compare
|
/rebase |
d928c6e to
39e0b42
Compare
|
/azp run maui-pr-uitests, maui-pr-devicetests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
🤖 AI Summary🚦 Test VerificationResult: ✅ PASSED Expand DetailsTest Verification ReportDate: 2026-01-26 15:36:16 | Platform: IOS | Status: ✅ PASSED Summary
✅ Final VerdictVERIFICATION PASSED ✅ The tests correctly detect the issue:
Conclusion: The tests properly validate the fix and catch the bug when it's present. ConfigurationPlatform: ios Fix Files
Test Results DetailsTest Run 1: WITHOUT FixExpected: Tests should FAIL (bug is present) Test Summary:
View full test output (without fix)Test Run 2: WITH FixExpected: Tests should PASS (bug is fixed) Test Summary:
View full test output (with fix)Logs
🔧 Try-Fix AnalysisSummary: 9 passed, 1 failed out of 10 attempts Attempt 1: **Model:** Claude Sonnet 4.5 ✅ PASSAttempt 1: Expand Footer HeightModel: Claude Sonnet 4.5 Approach: Instead of adjusting the Y position upward, expand the footer height to include the safe area. var adjustedHeight = footerHeight + View.SafeAreaInsets.Bottom;
_footerView.Frame = new CGRect(0, View.Frame.Height - adjustedHeight, footerWidth, adjustedHeight);Result: ✅ PASS Attempt 2: **Model:** Gemini 3 Pro ✅ PASSAttempt 2: SafeAreaLayoutGuide + ViewDidLayoutSubviewsModel: Gemini 3 Pro Approach: Use nfloat bottomY = View.SafeAreaLayoutGuide.LayoutFrame.Y + View.SafeAreaLayoutGuide.LayoutFrame.Height;
_footerView.Frame = new CGRect(0, bottomY - footerHeight, footerWidth, footerHeight);Result: ✅ PASS Attempt 3: Approach: calculate footer safe-area offset based on footer view's safe area rules (margin not se... ✅ PASSApproach: calculate footer safe-area offset based on footer view's safe area rules (margin not set, IgnoreSafeArea not set) and use UIApplication safe area insets for placement instead of a blanket View.SafeAreaInsets subtraction. This keeps the fix localized to footer positioning while honoring footer-specific safe area behavior. Fix Diffdiff --git a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutContentRenderer.cs b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutContentRenderer.cs
index d0497df394..743dc35d73 100644
--- a/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutContentRenderer.cs
+++ b/src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutContentRenderer.cs
@@ -216,12 +216,24 @@ namespace Microsoft.Maui.Controls.Platform.Compatibility
return;
var footerWidth = View.Frame.Width;
+ var safeAreaBottom = GetFooterSafeAreaBottom();
- _footerView.Frame = new CoreGraphics.CGRect(0, View.Frame.Height - footerHeight, footerWidth, footerHeight);
+ _footerView.Frame = new CoreGraphics.CGRect(0, View.Frame.Height - footerHeight - safeAreaBottom, footerWidth, footerHeight);
_tableViewController.LayoutParallax();
}
+ nfloat GetFooterSafeAreaBottom()
+ {
+ if (_footer is null || _footer.IsSet(Microsoft.Maui.Controls.View.MarginProperty))
+ return 0;
+
+ if (_footer is ISafeAreaView sav && sav.IgnoreSafeArea)
+ return 0;
+
+ return UIApplication.SharedApplication.GetSafeAreaInsetsForWindow().Bottom;
+ }
+
public override void ViewWillLayoutSubviews()
{
base.ViewWillLayoutSubviews();
@@ -236,6 +248,7 @@ namespace Microsoft.Maui.Controls.Platform.Compatibility
}
}
+
protected virtual void UpdateBackground()
{
var color = _shellContext.Shell.FlyoutBackgroundColor;
AnalysisResult: PASS. The footer Y position now subtracts a computed safe-area bottom that respects whether the footer view has an explicit margin or ignores safe area. This differs from the current fix by using the shared window safe-area and only applying it when appropriate for the footer view. Result: ✅ PASS Attempt 4: **Model:** GPT-5.1 ❌ FAILAttempt 4: Table View adjustedContentInsetModel: GPT-5.1 Approach: Use table view's nfloat bottomInset = tableView.AdjustedContentInset.Bottom;
_footerView.Frame = new CGRect(0, View.Frame.Height - footerHeight - bottomInset, footerWidth, footerHeight);Result: FAILED - Wrong abstraction level for footer positioning. Attempt 5: **Model:** Claude Sonnet 4 ✅ PASSAttempt 5: SafeAreaLayoutGuide.GetMaxY() HelperModel: Claude Sonnet 4 Approach: Use var safeLayoutFrame = View.SafeAreaLayoutGuide.LayoutFrame;
var footerY = safeLayoutFrame.Bottom - footerHeight;
_footerView.Frame = new CGRect(0, footerY, footerWidth, footerHeight);Result: ✅ PASS Attempt 6: **Model:** Claude Opus 4.5 ✅ PASSAttempt 6: Architectural - ShellFlyoutFooterContainerModel: Claude Opus 4.5 Approach: Create dedicated
Attempt 7: **Model:** Claude Sonnet 4 ✅ PASSAttempt 7: Regression-Safe with Dynamic UpdatesModel: Claude Sonnet 4 Approach: Mirror header's safe area API usage with Uses Attempt 8: **Model:** GPT-5.1 Codex ✅ PASSAttempt 8: Auto Layout ConstraintsModel: GPT-5.1 Codex Approach: Anchor footer to safe area using Auto Layout constraints instead of manual frame calculation.
Attempt 9: Approach: Keep the existing footer frame math, but move the footer above the bottom safe area usi... ✅ PASSApproach: Keep the existing footer frame math, but move the footer above the bottom safe area using a UIView Transform. Why this is different:
Implementation:
AnalysisResult: PASS (HeaderFooterShellFlyout) What happened:
Why it likely works:
Risks/notes:
Result: ✅ PASS Attempt 10: **Model:** Claude Haiku 4.5 ✅ PASSAttempt 10: Simple SafeArea OffsetModel: Claude Haiku 4.5 Approach: Direct subtraction of nfloat footerY = View.Frame.Height - footerHeight - View.SafeAreaInsets.Bottom;
_footerView.Frame = new CGRect(0, footerY, footerWidth, footerHeight);This is the simplest possible fix - same as the current PR. |
📋 PR Finalization ReviewReview 1: Finalization review
|
74da379 to
228ef12
Compare
) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Description of Change Footer position calculation in `ShellFlyoutContentRenderer.UpdateFooterPosition()` did not account for `SafeAreaInsets.Bottom`, causing footers with horizontal `StackLayout` to render below the visible area. ```csharp // Before _footerView.Frame = new CGRect(0, View.Frame.Height - footerHeight, footerWidth, footerHeight); // After var footerY = View.Frame.Height - footerHeight - View.SafeAreaInsets.Bottom; _footerView.Frame = new CGRect(0, footerY, footerWidth, footerHeight); ``` Also enabled horizontal orientation in `HeaderFooterShellFlyout` test case that was previously commented out due to this bug. ### Issues Fixed Fixes #26395 > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `4zjvsblobprodcus390.vsblob.vsassets.io` > - Triggering command: `/home/REDACTED/work/maui/maui/.dotnet/dotnet dotnet restore src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/kubaflo/maui/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > can you please work on this #26395 </details> > **Custom agent used: issue-resolver** > Specialized agent for investigating and resolving community-reported .NET MAUI issues through hands-on testing and implementation <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.
) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Description of Change Footer position calculation in `ShellFlyoutContentRenderer.UpdateFooterPosition()` did not account for `SafeAreaInsets.Bottom`, causing footers with horizontal `StackLayout` to render below the visible area. ```csharp // Before _footerView.Frame = new CGRect(0, View.Frame.Height - footerHeight, footerWidth, footerHeight); // After var footerY = View.Frame.Height - footerHeight - View.SafeAreaInsets.Bottom; _footerView.Frame = new CGRect(0, footerY, footerWidth, footerHeight); ``` Also enabled horizontal orientation in `HeaderFooterShellFlyout` test case that was previously commented out due to this bug. ### Issues Fixed Fixes #26395 > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `4zjvsblobprodcus390.vsblob.vsassets.io` > - Triggering command: `/home/REDACTED/work/maui/maui/.dotnet/dotnet dotnet restore src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/kubaflo/maui/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > can you please work on this #26395 </details> > **Custom agent used: issue-resolver** > Specialized agent for investigating and resolving community-reported .NET MAUI issues through hands-on testing and implementation <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.
) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Description of Change Footer position calculation in `ShellFlyoutContentRenderer.UpdateFooterPosition()` did not account for `SafeAreaInsets.Bottom`, causing footers with horizontal `StackLayout` to render below the visible area. ```csharp // Before _footerView.Frame = new CGRect(0, View.Frame.Height - footerHeight, footerWidth, footerHeight); // After var footerY = View.Frame.Height - footerHeight - View.SafeAreaInsets.Bottom; _footerView.Frame = new CGRect(0, footerY, footerWidth, footerHeight); ``` Also enabled horizontal orientation in `HeaderFooterShellFlyout` test case that was previously commented out due to this bug. ### Issues Fixed Fixes #26395 > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `4zjvsblobprodcus390.vsblob.vsassets.io` > - Triggering command: `/home/REDACTED/work/maui/maui/.dotnet/dotnet dotnet restore src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/kubaflo/maui/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > can you please work on this #26395 </details> > **Custom agent used: issue-resolver** > Specialized agent for investigating and resolving community-reported .NET MAUI issues through hands-on testing and implementation <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.
#33838) This pull request updates several UI test cases to improve reliability and platform compatibility. The main changes include updating element identifiers to match the UI, adjusting platform-specific test logic, and conditionally excluding a test that fails on Windows. **Test identifier updates and logic fixes:** * Updated the test automation IDs in Issue17823.cs, replacing grid-based elements with label-based elements (ReorderItemLabel0 / ReorderItemLabel3) to ensure Windows compatibility. The drag-and-drop test was also simplified by removing assert validations, as the DragAndDrop method does not always drop items reliably, which could cause intermittent assertion failures. * Due to the fix introduced in PR #32891, the FlyoutHeaderContentAndFooterAllMeasureCorrectly and FlyoutContentSetsCorrectBottomPaddingWhenMinHeightIsSetForFlyoutHeader test began failing; the test has now been updated and is working as expected. * Modified back button tap logic in `Issue33688.cs` to use platform-specific methods for Android/Windows and iOS/MacCatalyst, improving test reliability across platforms. * Wrapped the test in `Issue20772.cs` with a conditional to exclude it from running on Windows, referencing a known issue. [[1]](diffhunk://#diff-30ca65fc7efd27af71e093ab79eb601572bf186e770462550615e731de66d316R1) [[2]](diffhunk://#diff-30ca65fc7efd27af71e093ab79eb601572bf186e770462550615e731de66d316R53) Candidate PR: #33779
) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Description of Change Footer position calculation in `ShellFlyoutContentRenderer.UpdateFooterPosition()` did not account for `SafeAreaInsets.Bottom`, causing footers with horizontal `StackLayout` to render below the visible area. ```csharp // Before _footerView.Frame = new CGRect(0, View.Frame.Height - footerHeight, footerWidth, footerHeight); // After var footerY = View.Frame.Height - footerHeight - View.SafeAreaInsets.Bottom; _footerView.Frame = new CGRect(0, footerY, footerWidth, footerHeight); ``` Also enabled horizontal orientation in `HeaderFooterShellFlyout` test case that was previously commented out due to this bug. ### Issues Fixed Fixes #26395 > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `4zjvsblobprodcus390.vsblob.vsassets.io` > - Triggering command: `/home/REDACTED/work/maui/maui/.dotnet/dotnet dotnet restore src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/kubaflo/maui/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > can you please work on this #26395 </details> > **Custom agent used: issue-resolver** > Specialized agent for investigating and resolving community-reported .NET MAUI issues through hands-on testing and implementation <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.
#33838) This pull request updates several UI test cases to improve reliability and platform compatibility. The main changes include updating element identifiers to match the UI, adjusting platform-specific test logic, and conditionally excluding a test that fails on Windows. **Test identifier updates and logic fixes:** * Updated the test automation IDs in Issue17823.cs, replacing grid-based elements with label-based elements (ReorderItemLabel0 / ReorderItemLabel3) to ensure Windows compatibility. The drag-and-drop test was also simplified by removing assert validations, as the DragAndDrop method does not always drop items reliably, which could cause intermittent assertion failures. * Due to the fix introduced in PR #32891, the FlyoutHeaderContentAndFooterAllMeasureCorrectly and FlyoutContentSetsCorrectBottomPaddingWhenMinHeightIsSetForFlyoutHeader test began failing; the test has now been updated and is working as expected. * Modified back button tap logic in `Issue33688.cs` to use platform-specific methods for Android/Windows and iOS/MacCatalyst, improving test reliability across platforms. * Wrapped the test in `Issue20772.cs` with a conditional to exclude it from running on Windows, referencing a known issue. [[1]](diffhunk://#diff-30ca65fc7efd27af71e093ab79eb601572bf186e770462550615e731de66d316R1) [[2]](diffhunk://#diff-30ca65fc7efd27af71e093ab79eb601572bf186e770462550615e731de66d316R53) Candidate PR: #33779
) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Description of Change Footer position calculation in `ShellFlyoutContentRenderer.UpdateFooterPosition()` did not account for `SafeAreaInsets.Bottom`, causing footers with horizontal `StackLayout` to render below the visible area. ```csharp // Before _footerView.Frame = new CGRect(0, View.Frame.Height - footerHeight, footerWidth, footerHeight); // After var footerY = View.Frame.Height - footerHeight - View.SafeAreaInsets.Bottom; _footerView.Frame = new CGRect(0, footerY, footerWidth, footerHeight); ``` Also enabled horizontal orientation in `HeaderFooterShellFlyout` test case that was previously commented out due to this bug. ### Issues Fixed Fixes #26395 > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `4zjvsblobprodcus390.vsblob.vsassets.io` > - Triggering command: `/home/REDACTED/work/maui/maui/.dotnet/dotnet dotnet restore src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/kubaflo/maui/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > can you please work on this #26395 </details> > **Custom agent used: issue-resolver** > Specialized agent for investigating and resolving community-reported .NET MAUI issues through hands-on testing and implementation <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.
#33838) This pull request updates several UI test cases to improve reliability and platform compatibility. The main changes include updating element identifiers to match the UI, adjusting platform-specific test logic, and conditionally excluding a test that fails on Windows. **Test identifier updates and logic fixes:** * Updated the test automation IDs in Issue17823.cs, replacing grid-based elements with label-based elements (ReorderItemLabel0 / ReorderItemLabel3) to ensure Windows compatibility. The drag-and-drop test was also simplified by removing assert validations, as the DragAndDrop method does not always drop items reliably, which could cause intermittent assertion failures. * Due to the fix introduced in PR #32891, the FlyoutHeaderContentAndFooterAllMeasureCorrectly and FlyoutContentSetsCorrectBottomPaddingWhenMinHeightIsSetForFlyoutHeader test began failing; the test has now been updated and is working as expected. * Modified back button tap logic in `Issue33688.cs` to use platform-specific methods for Android/Windows and iOS/MacCatalyst, improving test reliability across platforms. * Wrapped the test in `Issue20772.cs` with a conditional to exclude it from running on Windows, referencing a known issue. [[1]](diffhunk://#diff-30ca65fc7efd27af71e093ab79eb601572bf186e770462550615e731de66d316R1) [[2]](diffhunk://#diff-30ca65fc7efd27af71e093ab79eb601572bf186e770462550615e731de66d316R53) Candidate PR: #33779
) <!-- Please let the below note in for people that find this PR --> > [!NOTE] > Are you waiting for the changes in this PR to be merged? > It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you! ### Description of Change Footer position calculation in `ShellFlyoutContentRenderer.UpdateFooterPosition()` did not account for `SafeAreaInsets.Bottom`, causing footers with horizontal `StackLayout` to render below the visible area. ```csharp // Before _footerView.Frame = new CGRect(0, View.Frame.Height - footerHeight, footerWidth, footerHeight); // After var footerY = View.Frame.Height - footerHeight - View.SafeAreaInsets.Bottom; _footerView.Frame = new CGRect(0, footerY, footerWidth, footerHeight); ``` Also enabled horizontal orientation in `HeaderFooterShellFlyout` test case that was previously commented out due to this bug. ### Issues Fixed Fixes #26395 > [!WARNING] > > <details> > <summary>Firewall rules blocked me from connecting to one or more addresses (expand for details)</summary> > > #### I tried to connect to the following addresses, but was blocked by firewall rules: > > - `4zjvsblobprodcus390.vsblob.vsassets.io` > - Triggering command: `/home/REDACTED/work/maui/maui/.dotnet/dotnet dotnet restore src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj` (dns block) > > If you need me to access, download, or install something from one of these locations, you can either: > > - Configure [Actions setup steps](https://gh.io/copilot/actions-setup-steps) to set up my environment, which run before the firewall is enabled > - Add the appropriate URLs or hosts to the custom allowlist in this repository's [Copilot coding agent settings](https://github.com/kubaflo/maui/settings/copilot/coding_agent) (admins only) > > </details> <!-- START COPILOT CODING AGENT SUFFIX --> <details> <summary>Original prompt</summary> > can you please work on this #26395 </details> > **Custom agent used: issue-resolver** > Specialized agent for investigating and resolving community-reported .NET MAUI issues through hands-on testing and implementation <!-- START COPILOT CODING AGENT TIPS --> --- 💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more [Copilot coding agent tips](https://gh.io/copilot-coding-agent-tips) in the docs.
#33838) This pull request updates several UI test cases to improve reliability and platform compatibility. The main changes include updating element identifiers to match the UI, adjusting platform-specific test logic, and conditionally excluding a test that fails on Windows. **Test identifier updates and logic fixes:** * Updated the test automation IDs in Issue17823.cs, replacing grid-based elements with label-based elements (ReorderItemLabel0 / ReorderItemLabel3) to ensure Windows compatibility. The drag-and-drop test was also simplified by removing assert validations, as the DragAndDrop method does not always drop items reliably, which could cause intermittent assertion failures. * Due to the fix introduced in PR #32891, the FlyoutHeaderContentAndFooterAllMeasureCorrectly and FlyoutContentSetsCorrectBottomPaddingWhenMinHeightIsSetForFlyoutHeader test began failing; the test has now been updated and is working as expected. * Modified back button tap logic in `Issue33688.cs` to use platform-specific methods for Android/Windows and iOS/MacCatalyst, improving test reliability across platforms. * Wrapped the test in `Issue20772.cs` with a conditional to exclude it from running on Windows, referencing a known issue. [[1]](diffhunk://#diff-30ca65fc7efd27af71e093ab79eb601572bf186e770462550615e731de66d316R1) [[2]](diffhunk://#diff-30ca65fc7efd27af71e093ab79eb601572bf186e770462550615e731de66d316R53) Candidate PR: #33779
.NET MAUI inflight/candidate introduces significant improvements across all platforms with focus on quality, performance, and developer experience. This release includes 20 commits with various improvements, bug fixes, and enhancements. ## Blazor - Fix for BlazorWebView Back Navigation Issues on Android 13+ After Predictive Back Gesture Changes by @SuthiYuvaraj in #33213 <details> <summary>🔧 Fixes</summary> - [Back navigation different between .net 9 and .net 10 blazor hybrid](#32767) </details> ## CollectionView - [Android] Fix for CollectionView.EmptyView does not remeasure its height when the parent layout changes dynamically, causing incorrect sizing. by @BagavathiPerumal in #33559 <details> <summary>🔧 Fixes</summary> - [`CollectionView.EmptyView` does not remeasure its height when the parent layout changes dynamically, causing incorrect sizing.](#33324) </details> - [Android] Fixed CollectionView reordering last item by @vitalii-vov in #17825 <details> <summary>🔧 Fixes</summary> - [Android app crashes when dragging into CollectionView](#17823) </details> ## DateTimePicker - [iOS] Fix VoiceOver focus not shifting to Picker/DatePicker/TimePicker popups by @kubaflo in #33152 <details> <summary>🔧 Fixes</summary> - [Voiceover does not automatically shift focus to the "Category" popup when it opens.: A11y_Developer balance version .NET 10_Project_ScreenReader](#30746) </details> ## Dialogalert - [iOS 26] Fix DisplayPromptAsync maxLength not enforced due to new multi-range delegate by @Shalini-Ashokan in #33616 <details> <summary>🔧 Fixes</summary> - [[iOS 26.1] DisplayPromptAsync ignores maxLength and does not respect RTL FlowDirection](#33549) </details> ## Flyout - [iOS] Shell: Account for SafeArea when positioning flyout footer by @kubaflo in #32891 <details> <summary>🔧 Fixes</summary> - [[IOS] Footer not displaying in iOS when StackOrientation.Horizontal is set on FlyoutFooter](#26395) </details> ## Fonts - Hide obsolete FontSize values from IDE autocomplete by @noiseonwires in #33694 ## Gestures - Android pan fixes by @BurningLights in #21547 <details> <summary>🔧 Fixes</summary> - [Flickering occurs while updating the width of ContentView through PanGestureRecognizer.](#20772) </details> ## Navigation - Shell: Add duplicate route validation for sibling elements by @SubhikshaSf4851 in #32296 <details> <summary>🔧 Fixes</summary> - [OnNavigatedTo is not called when navigating from a specific page](#14000) </details> ## Picker - Improved Unfocus support for Picker on Mac Catalyst by @kubaflo in #33127 <details> <summary>🔧 Fixes</summary> - [When using voiceover unable to access expanded list of project combo box: A11y_.NET maui_user can creat a tak_Screen reader](#30897) - [Task and Project controls are not accessible with keyboard:A11y_.NET maui_User can create a new task_Keyboard](#30891) </details> ## SafeArea - [iOS] SafeArea: Return Empty for non-ISafeAreaView views (opt-in model) by @praveenkumarkarunanithi in #33526 <details> <summary>🔧 Fixes</summary> - [[iOS] SafeArea is not applied when a ContentPage uses a ControlTemplate](#33458) </details> ## Shell - [iOS] Fix ObjectDisposedException in TraitCollectionDidChange on window disposal by @jeremy-visionaid in #33353 <details> <summary>🔧 Fixes</summary> - [Intermittent crash on exit on MacCatalyst - ObjectDisposedException](#33352) </details> - [Issue-Resolver] Explicit fallback for BackButtonBehavior lookup by @kubaflo in #33204 <details> <summary>🔧 Fixes</summary> - [Setting BackButtonBehavior to not visible or not enabled does not work](#28570) - [BackButtonBehavior not bound](#33139) </details> ## Templates - [Templates] Remove redundant SemanticProperties.Description attribute by @kubaflo in #33621 <details> <summary>🔧 Fixes</summary> - [Task and Project controls are not accessible with keyboard:A11y_.NET maui_User can create a new task_Keyboard](#30891) - [Unable to select "Tags" when Voiceover is turned on.: A11y_Developer balance version .NET 10_Project_ScreenReader](#30749) </details> ## Theme - [Windows] Fix runtime theme update for controls and TitleBar by @Tamilarasan-Paranthaman in #31714 <details> <summary>🔧 Fixes</summary> - [[Windows][MacOS?] Change title bar color when switching light/dark theme at runtime](#12507) - [OS system components ignore app theme](#22058) - [[Mac Catalyst][Windows] TitleBar not reacting on UserAppTheme changes](#30518) - [In dark theme "Back" and "hamburger" button icon color contrast with background color is less than 3:1: A11y_.NET maui_User can get all the insights of Dashboard_Non text Contrast](#30807) - [`Switch` is invisible on `PointOver` when theme has changed](#31819) </details> ## Theming - [XSG] Fix Style Setters referencing source-generated bindable properties by @simonrozsival in #33562 ## Titlebar - [Windows] Fix TitleBar.IsVisible = false the caption buttons become unresponsive by @devanathan-vaithiyanathan in #33256 <details> <summary>🔧 Fixes</summary> - [When TitleBar.IsVisible = false the caption buttons become unresponsive on Windows](#33171) </details> ## WebView - Fix WebView JavaScript string escaping for backslashes and quotes by @StephaneDelcroix in #33726 ## Xaml - [XSG] Fix NaN value in XAML generating invalid code by @StephaneDelcroix in #33533 <details> <summary>🔧 Fixes</summary> - [[XSG] NaN value in XAML generates invalid code](#33532) </details> <details> <summary>📦 Other (1)</summary> - Remove InternalsVisibleTo attributes for .NET MAUI Community Toolkit by @jfversluis via @Copilot in #33442 </details> **Full Changelog**: main...inflight/candidate
Note
Are you waiting for the changes in this PR to be merged?
It would be very helpful if you could test the resulting artifacts from this PR and let us know in a comment if this change resolves your issue. Thank you!
Description of Change
Footer position calculation in
ShellFlyoutContentRenderer.UpdateFooterPosition()did not account forSafeAreaInsets.Bottom, causing footers with horizontalStackLayoutto render below the visible area.Also enabled horizontal orientation in
HeaderFooterShellFlyouttest case that was previously commented out due to this bug.Issues Fixed
Fixes #26395
Warning
Firewall rules blocked me from connecting to one or more addresses (expand for details)
I tried to connect to the following addresses, but was blocked by firewall rules:
4zjvsblobprodcus390.vsblob.vsassets.io/home/REDACTED/work/maui/maui/.dotnet/dotnet dotnet restore src/Controls/tests/TestCases.HostApp/Controls.TestCases.HostApp.csproj(dns block)If you need me to access, download, or install something from one of these locations, you can either:
Original prompt
💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.