-
Notifications
You must be signed in to change notification settings - Fork 1.9k
[Android/iOS] Fix Shell Flyout SafeArea Rendering #33335
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
[Android/iOS] Fix Shell Flyout SafeArea Rendering #33335
Conversation
|
/azp run maui-pr |
|
Azure Pipelines successfully started running 1 pipeline(s). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR fixes issue #32275 where Shell FlyoutItems were rendering inside the SafeArea on Android and iOS instead of respecting safe area insets in both portrait and landscape orientations. The fix simplifies the flyout layout logic on both platforms by removing complex conditional safe area handling and applying safe area insets more consistently.
Key Changes
- Simplified iOS flyout content layout to unconditionally apply safe area insets
- Removed iOS ScrollView content inset management logic
- Simplified Android window inset handling to apply uniform padding
- Fixed iOS footer positioning to account for bottom safe area insets
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutLayoutManager.cs | Removed SetHeaderContentInset body and simplified LayoutContent to unconditionally apply safe area insets to all flyout content |
| src/Controls/src/Core/Compatibility/Handlers/Shell/iOS/ShellFlyoutContentRenderer.cs | Updated footer positioning to account for bottom safe area insets |
| src/Controls/src/Core/Compatibility/Handlers/Shell/Android/ShellFlyoutTemplatedContentRenderer.cs | Simplified WindowsListener class by removing complex conditional padding logic and unused properties, now applies uniform padding to CoordinatorLayout |
| var contentY = parentBounds.Y + safeAreaInsets.Top; | ||
|
|
||
| var contentHeight = parentBounds.Height - safeAreaInsets.Top - safeAreaInsets.Bottom - footerHeight; |
Copilot
AI
Dec 31, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The new LayoutContent implementation unconditionally applies safe area insets to all flyout content, regardless of whether the content has explicit margin set. The old implementation used ShouldHonorSafeArea() to check if margins were explicitly set and would skip safe area insets in those cases. This could be a breaking change for apps that have flyout content with explicit margins that expect edge-to-edge behavior. Consider whether the content should respect explicit margin settings or ISafeAreaView.IgnoreSafeArea property to allow developers to opt out of safe area behavior when needed.
| var contentY = parentBounds.Y + safeAreaInsets.Top; | |
| var contentHeight = parentBounds.Height - safeAreaInsets.Top - safeAreaInsets.Bottom - footerHeight; | |
| // By default, apply safe area insets to the content. | |
| nfloat safeAreaTop = safeAreaInsets.Top; | |
| nfloat safeAreaBottom = safeAreaInsets.Bottom; | |
| // If the flyout content is a MAUI view, only honor safe areas when appropriate. | |
| if (Content is IView contentView && !ShouldHonorSafeArea(contentView)) | |
| { | |
| // When margins are explicitly set or safe areas are being ignored, | |
| // do not apply additional safe area insets here. | |
| safeAreaTop = 0; | |
| safeAreaBottom = 0; | |
| } | |
| var contentY = parentBounds.Y + safeAreaTop; | |
| var contentHeight = parentBounds.Height - safeAreaTop - safeAreaBottom - footerHeight; |
| var topInset = Math.Max(systemBars?.Top ?? 0, displayCutout?.Top ?? 0); | ||
| var rightInset = Math.Max(systemBars?.Right ?? 0, displayCutout?.Right ?? 0); | ||
| var bottomInset = Math.Max(systemBars?.Bottom ?? 0, displayCutout?.Bottom ?? 0); | ||
| var appbarLayout = v.FindDescendantView<AppBarLayout>((v) => true); |
Copilot
AI
Dec 31, 2025
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The variable 'appbarLayout' is declared but never used after the simplification of the inset logic. This variable was part of the complex conditional padding logic that has been removed. Consider removing this unused variable declaration to clean up the code.
| var appbarLayout = v.FindDescendantView<AppBarLayout>((v) => true); |
PureWeen
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Tests failing
Issue Details
On Android/iOS, Shell FlyoutItems are rendered inside the SafeArea.
Description of Change
Updated the Shell Flyout layout logic to ensure FlyoutItems are consistently rendered within the SafeArea for both portrait and landscape modes.
Issues Fixed
Fixes #32275
Output Screenshot
Android-Before.mov
Android-After.mov
iOS-Before.mov
iOS-After.mov