Skip to content

[Android] Fix for TabbedPage BottomNavigation BarBackgroundColor not extending to system navigation bar#33428

Merged
kubaflo merged 13 commits intodotnet:inflight/currentfrom
praveenkumarkarunanithi:fix-33344
Mar 4, 2026
Merged

[Android] Fix for TabbedPage BottomNavigation BarBackgroundColor not extending to system navigation bar#33428
kubaflo merged 13 commits intodotnet:inflight/currentfrom
praveenkumarkarunanithi:fix-33344

Conversation

@praveenkumarkarunanithi
Copy link
Copy Markdown
Contributor

@praveenkumarkarunanithi praveenkumarkarunanithi commented Jan 8, 2026

Root Cause

In Android Edge-to-Edge mode, the MauiWindowInsetListener was applying padding to the root view and consuming bottom insets. This prevented BottomNavigationView from receiving the system navigation bar insets, so it could not extend its background color into the navigation bar area—resulting in a visible gap between the tab bar and the screen edge.

Description of Change

When a TabbedPage uses ToolbarPlacement.Bottom, the fix applies bottom padding to contentView (the fragment container) instead of the root view, and passes bottom insets through without consuming them. This allows BottomNavigationView to receive the insets and extend its background color into the system navigation bar area, eliminating the gap.

Issues Fixed

Fixes #33344

Tested the behaviour in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Note:
This issue is Android-specific. Windows and macOS do not have a system navigation bar area at the bottom of the screen.

Screenshots

Before Issue Fix After Issue Fix
withoutfix withfix

@sheiksyedm sheiksyedm marked this pull request as ready for review January 16, 2026 12:19
Copilot AI review requested due to automatic review settings January 16, 2026 12:19
@sheiksyedm
Copy link
Copy Markdown
Contributor

/rebase

@sheiksyedm sheiksyedm added platform/android area-safearea Issues/PRs that have to do with the SafeArea functionality labels Jan 16, 2026
Copy link
Copy Markdown
Contributor

Copilot AI left a 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 an Android edge-to-edge mode issue where TabbedPage with ToolbarPlacement.Bottom did not extend the BarBackgroundColor into the system navigation bar area, leaving a visible gap. The fix changes how window insets are handled in MauiWindowInsetListener to apply bottom padding to the content view instead of the root view, and passes bottom insets through unconsumed so that BottomNavigationView can extend into the navigation bar area.

Changes:

  • Modified inset handling logic to apply bottom padding to content view instead of root view when bottom navigation is present
  • Removed appBarHasContent condition from inset consumption to allow SafeAreaExtensions overlap logic to handle padding correctly
  • Added a test to verify BottomNavigationView extends to screen bottom in edge-to-edge mode

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
src/Core/src/Platform/Android/MauiWindowInsetListener.cs Modified inset handling to pad content view instead of root view for bottom navigation, and pass through bottom insets unconsumed
src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Android.cs Added test to verify bottom navigation view extends to screen bottom with proper layout positioning

@rmarinho
Copy link
Copy Markdown
Member

rmarinho commented Feb 17, 2026

🤖 AI Summary

📊 Expand Full Review
🔍 Pre-Flight — Context & Validation
📝 Review SessionMerge branch 'fix-33344' of https://github.com/praveenkumarkarunanithi/maui into fix-33344 · f614303

Issue: #33344 - TabbedPage BottomNavigation BarBackgroundColor does not extend to system navigation bar area in Edge-to-Edge mode
Platforms Affected: Android (Android 15 / API 35+)
Milestone: .NET 10 SR5
Labels: platform/android, , partner/syncfusion, area-safeareacommunity
Files Changed: 1 fix file, 1 device test file

Issue Summary

In .NET MAUI 10 on Android 15 (API 35+), when using TabbedPage with ToolbarPlacement.Bottom, the BarBackgroundColor does not extend into the system navigation bar area (gesture bar / 3-button nav). This is a regression introduced in 10.0.0-rc.1 when Edge-to-Edge was enabled by default.

Root Cause (from PR)

MauiWindowInsetListener.ApplyDefaultWindowInsets was applying padding to the root view and consuming bottom insets (setting them to 0 in the returned WindowInsetsCompat). This prevented BottomNavigationView from receiving system navigation bar insets, so it could not extend its background into the nav bar area.

Files Changed

File Type Lines
src/Core/src/Platform/Android/MauiWindowInsetListener.cs Fix +19 / -8
src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Android.cs Device Test +43 / 0

PR Fix Summary

When hasBottomNav is true (TabbedPage with ToolbarPlacement.Bottom):

  1. Before: Padded root view with bottom inset only; consumed bottom insets (set to 0 in returned insets)
  2. After: Pads contentView with left, right, bottom system bar insets; passes ALL insets through unconsumed

Additional change: Removed appBarHasContent conditional from newSystemBars/newDisplayCutout construction, now always passing top insets through unconsumed.

Prior Agent Review Status

A prior agent review was posted to the PR. Gate FAILED in the prior run. The author has NOT updated the code since then (same commit SHA f614303).

Reviewer Comments (Copilot PR Reviewer - unresolved)

File:Line Concern Status
MauiWindowInsetListener.cs:281 Left/right insets on contentView may conflict with CoordinatorLayout NOT ADDRESSED behavior
MauiWindowInsetListener.cs:276 Comment should clarify padding covers nav bar + system nav NOT ADDRESSED bar
TabbedPageTests.Android.cs:250 Exact equality (==) for pixel positions is NOT ADDRESSED fragile

Key Concerns

  1. Left/right insets on contentView (Medium): Adds systemBars?.Left and systemBars?.Right to contentView not in original code and may cause double-padding in landscape mode.padding
  2. Removed appBarHasContent conditional (Medium): Top insets now ALWAYS passed through; this is unrelated to the bottom nav fix and could affect NavigationPage/Shell with top navigation bars.
  3. Test uses exact equality (Minor): screenHeight == bottomNavBottom should use Math.Abs(...) < 2 for robustness.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #33428 Pad contentView instead of root view; pass all insets through PENDING (Gate) MauiWindowInsetListener.cs (+19/-8) Original PR - 3 unaddressed review comments unconsumed

🚦 Gate — Test Verification
📝 Review SessionMerge branch 'fix-33344' of https://github.com/praveenkumarkarunanithi/maui into fix-33344 · f614303

** FAILEDResult:**
Platform: android
Mode: Full Verification (Two-Pass)

Gate Verification Results

Pass State Expected Actual Status
Pass 1 (WITHOUT fix) Fix reverted to origin/main FAIL FAIL OK
Pass 2 (WITH fix) Fix applied PASS BAD FAIL

Critical Finding: Test Does Not Pass With Fix Applied

The test BottomNavigationViewExtendsToScreenBottom failed in both passes:
Failed WITHOUT the fix (Pass 1 - "expected", but for wrong reason)-
Failed WITH the fix (Pass 2 - unexpected)-

Root Cause of Gate Failure

The test BottomNavigationViewExtendsToScreenBottom is located in the DeviceTests project:
src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Android.cs

The Gate verification uses BuildAndRunHostApp.ps1 which builds and runs the UI Test HostApp (TestCases.HostApp). Device tests are a completely separate project that runs via Helix on CI they cannot be run locally using the HostApp runner.infrastructure

The build succeeded (0 errors) but no tests matching the filter were executed because the test isn't in the HostApp project.

Environment Blocker: Device tests require Helix infrastructure (cloud-based device testing) to they cannot be verified locally with the available test scripts.run

Prior Review Corroboration

The prior agent review (same commit f614303) also found Gate FAILED, describing the test as "passing both with and without the fix" in that environment. This is consistent - in both environments, the Gate infrastructure cannot properly verify this device test.

Gate Status

** FAILED**GATE:

Fix phase (try-fix) skipped: Cannot explore alternative fixes without a reliable local test to verify against.


🔧 Fix — Analysis & Comparison
📝 Review SessionMerge branch 'fix-33344' of https://github.com/praveenkumarkarunanithi/maui into fix-33344 · f614303

Fix Phase: Skipped - Gate Failed

Reason: Phase 3 (try-fix) was skipped because Gate failed.

The test BottomNavigationViewExtendsToScreenBottom is a device test that runs via Helix infrastructure (not locally via the HostApp runner). Without a reliable local test to validate fix candidates against, try-fix exploration cannot be performed.

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #33428 Pad contentView instead of root view; pass all insets through UNVERIFIED (Gate failed) MauiWindowInsetListener.cs (+19/-8) Test doesn't run locally unconsumed

Exhausted: N/A (skipped due to Gate failure - environment blocker)
Selected Fix: N/A - Cannot select without reliable tests


📋 Report — Final Recommendation
📝 Review SessionMerge branch 'fix-33344' of https://github.com/praveenkumarkarunanithi/maui into fix-33344 · f614303

Final Recommendation: REQUEST CHANGES##

Summary

PR #33428 addresses a real regression in .NET MAUI 10 where TabbedPage with ToolbarPlacement.Bottom doesn't extend BarBackgroundColor into the system navigation bar area on Android 15+ in Edge-to-Edge mode. The core fix direction (padding contentView instead of the root view, passing insets through unconsumed) is correct in principle. However, the PR has three significant technical issues plus a test verification problem that require the author's attention before it can be merged.

Root Cause Analysis

In Android Edge-to-Edge mode (API 35+), MauiWindowInsetListener.ApplyDefaultWindowInsets was applying bottom padding to the root view and consuming bottom insets (setting them to 0 in the returned WindowInsetsCompat). Since BottomNavigationView never received the system navigation bar insets, it could not extend its background color into the navigation bar leaving a visible gap between the tab bar and the screen edge.area

Gate Verification

  • Platform tested: Android
  • Test: BottomNavigationViewExtendsToScreenBottom in TabbedPageTests.Android.cs (DeviceTests)
  • Gate Environment blocker: the test is a device test (Helix infrastructure) and cannot be verified locally via the HostApp runner. Both passes failed, consistent with the prior agent review which also found Gate FAILED.FAILED status:

Fix Analysis

Change Assessment Verdict
Pad instead of root view prevents content area from being squished by the system nav bar Correct Good
Pass bottom insets through unconsumed allows to extend its background into nav bar area Required Good
Apply left/right insets to contentView Not needed for the fix; may cause unexpected padding in landscape mode with Remove cutouts
Remove appBarHasContent from top insets Unrelated change; changes inset behavior for ALL layouts (NavigationPage, Shell); regression Revert risk
Test uses exact equality for pixel positions Fragile; 1px rounding differences common on Fix Android

Required Changes

Issue 1 (Critical): Test does not reliably verify the fix

The test BottomNavigationViewExtendsToScreenBottom measures whether BottomNavigationView's bottom pixel coordinate equals the screen height. In Edge-to-Edge mode, BottomNavigationView is often already laid out to the physical screen bottom regardless of inset the visual gap is caused by the background color not extending, not by the view's position being different.state

A more reliable test would:

  • Verify that contentView's bottom padding equals the system navigation bar inset height when hasBottomNav is true
  • OR verify that the root view does NOT have bottom padding in the bottom-nav scenario

Issue 2 (Medium): Remove left/right insets from contentView padding

The original code only applied bottom padding to the root view. The fix introduces left/right insets on contentView which:

  1. Are not needed for the bug fix
  2. Were not in the original code
  3. May cause unexpected behavior in landscape orientation with display cutouts
// Change this:
contentView?.SetPadding(
    systemBars?.Left ?? 0,
    0,
    systemBars?.Right ?? 0,
    bottomInset);

// To this:
contentView?.SetPadding(0, 0, 0, bottomInset);

Issue 3 (Medium): Revert the appBarHasContent inset consumption change

Removing the appBarHasContent ? 0 : systemBars?.Top ?? 0 conditional changes behavior for all layouts, not just TabbedPage bottom navigation. This is unrelated to the bug fix, was not explained in the PR description, and has no accompanying tests for NavigationPage/Shell scenarios.

// Revert to original:
var newSystemBars = Insets.Of(
    systemBars?.Left ?? 0,
    appBarHasContent ? 0 : systemBars?.Top ?? 0,
    systemBars?.Right ?? 0,
    hasBottomNav ? 0 : systemBars?.Bottom ?? 0
) ?? Insets.None;

Issue 4 (Minor): Test tolerance

// Change:
Assert.True(screenHeight == bottomNavBottom, ...);
// To:
Assert.True(Math.Abs(screenHeight - bottomNavBottom) < 2, ...);

Prior Review Status

This is the second agent review of this PR. The prior review (posted 2026-02-17) made the same recommendations. The author has NOT addressed any of the concerns since the review was posted (same commit SHA f614303).

There are also 3 unresolved inline review comments from the Copilot PR Reviewer (Jan 16, 2026) that align with findings none have been addressed.above


📋 Expand PR Finalization Review
Title: ✅ Good

Current: [Android] Fix for TabbedPage BottomNavigation BarBackgroundColor not extending to system navigation bar

Description: ✅ Good

Description needs updates. See details below.

✨ Suggested PR Description

[!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!

Root Cause

In Android Edge-to-Edge mode, the MauiWindowInsetListener was applying padding to the root view and consuming bottom insets. This prevented BottomNavigationView from receiving the system navigation bar insets, so it could not extend its background color into the navigation bar area—resulting in a visible gap between the tab bar and the screen edge.

Description of Change

When a TabbedPage uses ToolbarPlacement.Bottom, the fix applies bottom padding to contentView (the fragment container) instead of the root view, and passes bottom insets through without consuming them. This allows BottomNavigationView to receive the insets and extend its background color into the system navigation bar area, eliminating the gap. Additionally, removed the appBarHasContent check from inset consumption since SafeAreaExtensions overlap logic already correctly determines padding for child views based on their screen position.

Issues Fixed

Fixes #33344

Tested the behaviour in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Note:
This issue is Android-specific. Windows and macOS do not have a system navigation bar area at the bottom of the screen.

Screenshots

Before Issue Fix After Issue Fix
withoutfix withfix
Code Review: ✅ Passed

Code Review Findings — PR #33428

🟡 Suggestions

1. Test assertion uses exact pixel equality — could be fragile

File: src/Controls/tests/DeviceTests/Elements/TabbedPage/TabbedPageTests.Android.cs

Code:

Assert.True(screenHeight == bottomNavBottom,
    $"BottomNavigationView should extend to screen bottom. Expected bottom at {screenHeight}px, but was at {bottomNavBottom}px (gap of {screenHeight - bottomNavBottom}px)");

Problem: Pixel-exact equality (==) between BottomNavigationView's bottom and the DecorView's height may fail due to sub-pixel rounding or density differences on some devices/emulators.

Recommendation: Use a small tolerance (e.g., ±1px) to avoid flakiness:

var gap = screenHeight - bottomNavBottom;
Assert.True(Math.Abs(gap) <= 1,
    $"BottomNavigationView should extend to screen bottom. Expected bottom at {screenHeight}px, but was at {bottomNavBottom}px (gap of {gap}px)");

Or use Assert.Equal(screenHeight, bottomNavBottom) for a cleaner failure message without the tolerance concern.


2. Reconstructed Insets are identical to originals — effectively a pass-through

File: src/Core/src/Platform/Android/MauiWindowInsetListener.cs

Code (lines 291–308):

var newSystemBars = Insets.Of(
    systemBars?.Left ?? 0,
    systemBars?.Top ?? 0,
    systemBars?.Right ?? 0,
    systemBars?.Bottom ?? 0
) ?? Insets.None;

var newDisplayCutout = Insets.Of(
    displayCutout?.Left ?? 0,
    displayCutout?.Top ?? 0,
    displayCutout?.Right ?? 0,
    displayCutout?.Bottom ?? 0
) ?? Insets.None;

Observation: After the fix, newSystemBars and newDisplayCutout are now exact copies of the original values (no values are consumed/zeroed). The Insets reconstruction code is logically equivalent to passing insets unchanged. This isn't a bug, but it's unnecessary complexity that makes the code harder to reason about.

Recommendation (low priority): Simplify to just pass through the original insets:

// Previously consumed certain insets; now all passed through as SafeAreaExtensions handles positioning
return insets;

This makes the intent explicit and eliminates the dead Insets-construction code. However, this is purely cosmetic and can be left for a follow-up cleanup.


✅ Looks Good

  • Core fix approach is correct: Moving bottom padding from the root view to contentView is the right Android pattern. The root view consuming bottom insets was the root cause of BottomNavigationView not being able to extend into the gesture bar area.

  • Removal of appBarHasContent from inset forwarding is justified: The AppBarLayout already applies its own top padding directly (appBarLayout.SetPadding(...)). Consuming top insets in the forwarded values was redundant since SafeAreaExtensions uses screen-position-based overlap detection rather than relying on consumed insets. Passing insets through avoids over-consuming them for child views.

  • contentView padding includes horizontal insets: The new content-view padding (contentView?.SetPadding(systemBars?.Left ?? 0, 0, systemBars?.Right ?? 0, bottomInset)) correctly includes left/right side insets — an improvement over the old root-view padding that only handled bottom (v.SetPadding(0, 0, 0, bottomInset)).

  • Null-safe content view reset: The else branch resets contentView?.SetPadding(0, 0, 0, 0) to handle the case where bottom navigation is dynamically removed.

  • Test is well-structured: The test correctly verifies the end-to-end behavior (BottomNavigationView reaching the screen bottom) rather than just testing an internal API, providing good regression coverage.


@rmarinho rmarinho added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-lose Author adopted the agent's fix and it turned out to be bad s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Feb 17, 2026
Copy link
Copy Markdown
Contributor

@kubaflo kubaflo left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @praveenkumarkarunanithi what do you think about the suggestions from AI Summary

@rmarinho rmarinho added the s/agent-gate-failed AI could not verify tests catch the bug label Feb 18, 2026
@sheiksyedm sheiksyedm added the s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation label Feb 23, 2026
@kubaflo kubaflo removed the s/agent-changes-requested AI agent recommends changes - found a better alternative or issues label Feb 25, 2026
@kubaflo kubaflo changed the base branch from main to inflight/current March 4, 2026 23:31
@kubaflo kubaflo merged commit f3b2020 into dotnet:inflight/current Mar 4, 2026
24 of 27 checks passed
HarishKumarSF4517 pushed a commit to HarishKumarSF4517/maui that referenced this pull request Mar 5, 2026
…extending to system navigation bar (dotnet#33428)

### Root Cause
In Android `Edge-to-Edge` mode, the `MauiWindowInsetListener` was
applying padding to the root view and consuming bottom insets. This
prevented `BottomNavigationView` from receiving the system navigation
bar insets, so it could not extend its background color into the
navigation bar area—resulting in a visible gap between the tab bar and
the screen edge.
 
### Description of Change
When a `TabbedPage` uses `ToolbarPlacement.Bottom`, the fix applies
bottom padding to `contentView` (the fragment container) instead of the
root view, and passes bottom insets through without consuming them. This
allows `BottomNavigationView` to receive the insets and extend its
background color into the system navigation bar area, eliminating the
gap.

### Issues Fixed
Fixes dotnet#33344 
 
Tested the behaviour in the following platforms
- [x] Android
- [ ] Windows
- [x] iOS
- [ ] Mac

**Note:**
This issue is Android-specific. Windows and macOS do not have a system
navigation bar area at the bottom of the screen.

### Screenshots
| Before Issue Fix | After Issue Fix |
|------------------|-----------------|
| <img width="350" alt="withoutfix"
src="https://github.com/user-attachments/assets/878a0361-c0cd-4621-a063-94bbc757d15c"
/> | <img width="350" alt="withfix"
src="https://github.com/user-attachments/assets/ed552f1e-d75f-4275-856a-b8bf993a0dcd"
/> |
PureWeen pushed a commit that referenced this pull request Mar 11, 2026
…extending to system navigation bar (#33428)

### Root Cause
In Android `Edge-to-Edge` mode, the `MauiWindowInsetListener` was
applying padding to the root view and consuming bottom insets. This
prevented `BottomNavigationView` from receiving the system navigation
bar insets, so it could not extend its background color into the
navigation bar area—resulting in a visible gap between the tab bar and
the screen edge.
 
### Description of Change
When a `TabbedPage` uses `ToolbarPlacement.Bottom`, the fix applies
bottom padding to `contentView` (the fragment container) instead of the
root view, and passes bottom insets through without consuming them. This
allows `BottomNavigationView` to receive the insets and extend its
background color into the system navigation bar area, eliminating the
gap.

### Issues Fixed
Fixes #33344 
 
Tested the behaviour in the following platforms
- [x] Android
- [ ] Windows
- [x] iOS
- [ ] Mac

**Note:**
This issue is Android-specific. Windows and macOS do not have a system
navigation bar area at the bottom of the screen.

### Screenshots
| Before Issue Fix | After Issue Fix |
|------------------|-----------------|
| <img width="350" alt="withoutfix"
src="https://github.com/user-attachments/assets/878a0361-c0cd-4621-a063-94bbc757d15c"
/> | <img width="350" alt="withfix"
src="https://github.com/user-attachments/assets/ed552f1e-d75f-4275-856a-b8bf993a0dcd"
/> |
github-actions bot pushed a commit that referenced this pull request Mar 11, 2026
…extending to system navigation bar (#33428)

### Root Cause
In Android `Edge-to-Edge` mode, the `MauiWindowInsetListener` was
applying padding to the root view and consuming bottom insets. This
prevented `BottomNavigationView` from receiving the system navigation
bar insets, so it could not extend its background color into the
navigation bar area—resulting in a visible gap between the tab bar and
the screen edge.
 
### Description of Change
When a `TabbedPage` uses `ToolbarPlacement.Bottom`, the fix applies
bottom padding to `contentView` (the fragment container) instead of the
root view, and passes bottom insets through without consuming them. This
allows `BottomNavigationView` to receive the insets and extend its
background color into the system navigation bar area, eliminating the
gap.

### Issues Fixed
Fixes #33344 
 
Tested the behaviour in the following platforms
- [x] Android
- [ ] Windows
- [x] iOS
- [ ] Mac

**Note:**
This issue is Android-specific. Windows and macOS do not have a system
navigation bar area at the bottom of the screen.

### Screenshots
| Before Issue Fix | After Issue Fix |
|------------------|-----------------|
| <img width="350" alt="withoutfix"
src="https://github.com/user-attachments/assets/878a0361-c0cd-4621-a063-94bbc757d15c"
/> | <img width="350" alt="withfix"
src="https://github.com/user-attachments/assets/ed552f1e-d75f-4275-856a-b8bf993a0dcd"
/> |
@PureWeen PureWeen mentioned this pull request Mar 17, 2026
jfversluis pushed a commit that referenced this pull request Mar 18, 2026
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### RootCause of the issue

- In PR #33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for #33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state.
 
### Description of Change
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for #33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

### Test failures
- EntryScrollTest, HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape,
VerifyBindableLayoutWithGridItemTemplate - (EntryScrollTest)Test fails
due to #33428 this PR



### Issues Fixed

Fixes #34509
Ahamed-Ali added a commit to Ahamed-Ali/maui that referenced this pull request Mar 19, 2026
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### RootCause of the issue

- In PR dotnet#33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for dotnet#33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state.
 
### Description of Change
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for dotnet#33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

### Test failures
- EntryScrollTest, HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape,
VerifyBindableLayoutWithGridItemTemplate - (EntryScrollTest)Test fails
due to dotnet#33428 this PR



### Issues Fixed

Fixes dotnet#34509
PureWeen pushed a commit that referenced this pull request Mar 19, 2026
…extending to system navigation bar (#33428)

### Root Cause
In Android `Edge-to-Edge` mode, the `MauiWindowInsetListener` was
applying padding to the root view and consuming bottom insets. This
prevented `BottomNavigationView` from receiving the system navigation
bar insets, so it could not extend its background color into the
navigation bar area—resulting in a visible gap between the tab bar and
the screen edge.
 
### Description of Change
When a `TabbedPage` uses `ToolbarPlacement.Bottom`, the fix applies
bottom padding to `contentView` (the fragment container) instead of the
root view, and passes bottom insets through without consuming them. This
allows `BottomNavigationView` to receive the insets and extend its
background color into the system navigation bar area, eliminating the
gap.

### Issues Fixed
Fixes #33344 
 
Tested the behaviour in the following platforms
- [x] Android
- [ ] Windows
- [x] iOS
- [ ] Mac

**Note:**
This issue is Android-specific. Windows and macOS do not have a system
navigation bar area at the bottom of the screen.

### Screenshots
| Before Issue Fix | After Issue Fix |
|------------------|-----------------|
| <img width="350" alt="withoutfix"
src="https://github.com/user-attachments/assets/878a0361-c0cd-4621-a063-94bbc757d15c"
/> | <img width="350" alt="withfix"
src="https://github.com/user-attachments/assets/ed552f1e-d75f-4275-856a-b8bf993a0dcd"
/> |
jfversluis pushed a commit that referenced this pull request Mar 20, 2026
### Root Cause of the issue



- The failing test: `SetVisibility(Visibility.Collapsed)` device test on
iOS.

  Why it fails: PR #28983's fix maps Visibility → MapIsRunning in
  ActivityIndicatorHandler, which bypasses the standard
ViewExtensions.UpdateVisibility path. The standard path calls Collapse()
to
add a CollapseConstraint (an NSLayoutConstraint that zeros the view's
size).
The PR's UpdateIsRunning only sets Hidden = true — it never calls
Collapse()
- Crash in the FeatureMatrix Navigation Page Scenario in the iOS 26
PR #34326 added an else block in UpdateBarTextColor() that explicitly
sets BackButtonAppearance = null, BackIndicatorImage = null, and
BackIndicatorTransitionMaskImage = null on the navigation bar when no
custom color is applied. On iOS versions before 26, assigning null to
these properties was treated as "use system defaults." On iOS 26, the
Liquid Glass rendering pipeline reads these properties during push/pop
navigation transitions and throws an exception when it encounters an
explicit null — it expects either an unset property or a valid object.
Since useCustomColor is false by default (no IconColor set), this
crashes on every standard page navigation.
- Setting ThumbTintList = null in the else block removes the tint
entirely, causing the thumb to appear white instead of the default blue,
because SwitchCompat does not re-resolve its theme colors once the tint
list is cleared.
- SetAdjustViewBounds(false) was being applied to all images regardless
of their Aspect value. When this property is false, Android’s ImageView
does not resize itself based on the image’s intrinsic aspect ratio and
instead expands to fill the available space. As a result, an Image
control with the default AspectFit setting ignored its height constraint
and overflowed its container, causing the image to appear taller than
expected in the screenshot test.(LoadAndVerifyGif, ThemeRelated feature
tests)
- PR #29144 changed the group-detection guard in ObservableGroupedSource
(iOS and Android) from is IEnumerable to is ICollection to prevent
strings (which implement IEnumerable<char>) from being treated as
groups.
While the intent was correct, the change was too broad. Custom group
types that implement only IEnumerable<T> were also excluded. As a
result, _groupCount became zero on iOS and _groups remained empty on
Android, causing grouped CollectionView rendering failures and
IndexOutOfRangeException during Add/Remove operations.
- StepperHandler.iOS.cs compiles for both iOS and Mac Catalyst. On Mac
Catalyst / macOS 26, OperatingSystem.IsIOS() and IsIOSVersionAtLeast(26)
both return true, and the screen is always landscape. As a result, the
20pt glass pill compensation was incorrectly applied, inflating
GetDesiredSize(1,1) to width = 21. (Native View Bounding Box is not
empty - device Test failures)
- In PR #33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for #33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state. (EntryScrollTest,
HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape and so on failures)

### Description of Change



- Handles the three Visibility cases the same way as
ViewExtensions.UpdateVisibility:

`Visible`: Calls Inflate() (restores layout size) and sets Hidden =
false — identical to UpdateVisibility. Additionally starts/stops the
animation based on IsRunning.
`Hidden`: Calls Inflate() (preserves layout space) and sets Hidden =
true — identical to UpdateVisibility. The indicator keeps its layout
footprint but is invisible.
`Collapsed`: Sets Hidden = true and calls Collapse() (zeros out layout
size via constraints) — identical to UpdateVisibility. The indicator is
both invisible and takes up no space.
- Removed the else block entirely. When no custom color is applied,
these properties should remain untouched. The system defaults work
correctly on their own — there is no need to explicitly reset them to
null
- Removed the else block from UpdateThumbColor in SwitchExtensions.cs.
The default thumb color is managed by SwitchCompat internally from the
Material theme, so no explicit reset is needed.
- Restored the correct logic in ImageViewExtensions.UpdateAspect to call
SetAdjustViewBounds based on the image’s Aspect value:
- The guard has been updated from is ICollection to is IEnumerable &&
not string in the ObservableGroupedSource implementations for both iOS
and Android (GroupsCount(), UpdateGroupTracking(), Add(), Remove()).
This change specifically excludes string while allowing legitimate
custom group types that implement only IEnumerable<T>. The fix restores
the behavior for Issue22320 while keeping all Issue29141 scenarios
working correctly.
-Added !OperatingSystem.IsMacCatalyst() to the guard condition in
GetDesiredSize, restricting the 20pt compensation to real iOS 26+ only —
as intended in the original PR comment.
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for #33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

### Testing related description of change
EditorNoOverlapAfterRotateToLandscape,
EditorNoOverlapAfterRotateToPortrait,
EntryFocusedShouldNotCauseGapAfterRotation Added cropLeft to remove the
navbar on Android and re-saved the image due to entry text changes in
this commit –
8d17a6d,
91047fb.

DrawStringShouldDrawText – The automation ID set to GraphicsView was not
found by Appium on the Windows platform, so a test condition was added
for Windows to take the image directly instead of waiting for the
GraphicsView.

Added the base images for iOS 26 and Mac that were not added previously.

Re-saved the images that failed due to the wrong iOS version image being
added in the PR.

Re-saved the test images that failed due to this fix PR:
#31254 — e.g.,
GraphicsViewFeatureTests and others.
 
Resaved the slider-related test images due to this fix PR —
#34064.

### Issues Fixed




Fixes #34437 



### Tested the behaviour in the following platforms



- [x] iOS
- [x] Mac

---------

Co-authored-by: SyedAbdulAzeem <syedabdulazeem.a@syncfusion.com>
Co-authored-by: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com>
Co-authored-by: TamilarasanSF4853 <tamilarasan.velu@syncfusion.com>
Co-authored-by: LogishaSelvarajSF4525 <logisha.selvaraj@syncfusion.com>
github-actions bot pushed a commit that referenced this pull request Mar 20, 2026
…extending to system navigation bar (#33428)

### Root Cause
In Android `Edge-to-Edge` mode, the `MauiWindowInsetListener` was
applying padding to the root view and consuming bottom insets. This
prevented `BottomNavigationView` from receiving the system navigation
bar insets, so it could not extend its background color into the
navigation bar area—resulting in a visible gap between the tab bar and
the screen edge.
 
### Description of Change
When a `TabbedPage` uses `ToolbarPlacement.Bottom`, the fix applies
bottom padding to `contentView` (the fragment container) instead of the
root view, and passes bottom insets through without consuming them. This
allows `BottomNavigationView` to receive the insets and extend its
background color into the system navigation bar area, eliminating the
gap.

### Issues Fixed
Fixes #33344 
 
Tested the behaviour in the following platforms
- [x] Android
- [ ] Windows
- [x] iOS
- [ ] Mac

**Note:**
This issue is Android-specific. Windows and macOS do not have a system
navigation bar area at the bottom of the screen.

### Screenshots
| Before Issue Fix | After Issue Fix |
|------------------|-----------------|
| <img width="350" alt="withoutfix"
src="https://github.com/user-attachments/assets/878a0361-c0cd-4621-a063-94bbc757d15c"
/> | <img width="350" alt="withfix"
src="https://github.com/user-attachments/assets/ed552f1e-d75f-4275-856a-b8bf993a0dcd"
/> |
github-actions bot pushed a commit that referenced this pull request Mar 20, 2026
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### RootCause of the issue

- In PR #33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for #33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state.
 
### Description of Change
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for #33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

### Test failures
- EntryScrollTest, HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape,
VerifyBindableLayoutWithGridItemTemplate - (EntryScrollTest)Test fails
due to #33428 this PR



### Issues Fixed

Fixes #34509
github-actions bot pushed a commit that referenced this pull request Mar 20, 2026
### Root Cause of the issue



- The failing test: `SetVisibility(Visibility.Collapsed)` device test on
iOS.

  Why it fails: PR #28983's fix maps Visibility → MapIsRunning in
  ActivityIndicatorHandler, which bypasses the standard
ViewExtensions.UpdateVisibility path. The standard path calls Collapse()
to
add a CollapseConstraint (an NSLayoutConstraint that zeros the view's
size).
The PR's UpdateIsRunning only sets Hidden = true — it never calls
Collapse()
- Crash in the FeatureMatrix Navigation Page Scenario in the iOS 26
PR #34326 added an else block in UpdateBarTextColor() that explicitly
sets BackButtonAppearance = null, BackIndicatorImage = null, and
BackIndicatorTransitionMaskImage = null on the navigation bar when no
custom color is applied. On iOS versions before 26, assigning null to
these properties was treated as "use system defaults." On iOS 26, the
Liquid Glass rendering pipeline reads these properties during push/pop
navigation transitions and throws an exception when it encounters an
explicit null — it expects either an unset property or a valid object.
Since useCustomColor is false by default (no IconColor set), this
crashes on every standard page navigation.
- Setting ThumbTintList = null in the else block removes the tint
entirely, causing the thumb to appear white instead of the default blue,
because SwitchCompat does not re-resolve its theme colors once the tint
list is cleared.
- SetAdjustViewBounds(false) was being applied to all images regardless
of their Aspect value. When this property is false, Android’s ImageView
does not resize itself based on the image’s intrinsic aspect ratio and
instead expands to fill the available space. As a result, an Image
control with the default AspectFit setting ignored its height constraint
and overflowed its container, causing the image to appear taller than
expected in the screenshot test.(LoadAndVerifyGif, ThemeRelated feature
tests)
- PR #29144 changed the group-detection guard in ObservableGroupedSource
(iOS and Android) from is IEnumerable to is ICollection to prevent
strings (which implement IEnumerable<char>) from being treated as
groups.
While the intent was correct, the change was too broad. Custom group
types that implement only IEnumerable<T> were also excluded. As a
result, _groupCount became zero on iOS and _groups remained empty on
Android, causing grouped CollectionView rendering failures and
IndexOutOfRangeException during Add/Remove operations.
- StepperHandler.iOS.cs compiles for both iOS and Mac Catalyst. On Mac
Catalyst / macOS 26, OperatingSystem.IsIOS() and IsIOSVersionAtLeast(26)
both return true, and the screen is always landscape. As a result, the
20pt glass pill compensation was incorrectly applied, inflating
GetDesiredSize(1,1) to width = 21. (Native View Bounding Box is not
empty - device Test failures)
- In PR #33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for #33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state. (EntryScrollTest,
HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape and so on failures)

### Description of Change



- Handles the three Visibility cases the same way as
ViewExtensions.UpdateVisibility:

`Visible`: Calls Inflate() (restores layout size) and sets Hidden =
false — identical to UpdateVisibility. Additionally starts/stops the
animation based on IsRunning.
`Hidden`: Calls Inflate() (preserves layout space) and sets Hidden =
true — identical to UpdateVisibility. The indicator keeps its layout
footprint but is invisible.
`Collapsed`: Sets Hidden = true and calls Collapse() (zeros out layout
size via constraints) — identical to UpdateVisibility. The indicator is
both invisible and takes up no space.
- Removed the else block entirely. When no custom color is applied,
these properties should remain untouched. The system defaults work
correctly on their own — there is no need to explicitly reset them to
null
- Removed the else block from UpdateThumbColor in SwitchExtensions.cs.
The default thumb color is managed by SwitchCompat internally from the
Material theme, so no explicit reset is needed.
- Restored the correct logic in ImageViewExtensions.UpdateAspect to call
SetAdjustViewBounds based on the image’s Aspect value:
- The guard has been updated from is ICollection to is IEnumerable &&
not string in the ObservableGroupedSource implementations for both iOS
and Android (GroupsCount(), UpdateGroupTracking(), Add(), Remove()).
This change specifically excludes string while allowing legitimate
custom group types that implement only IEnumerable<T>. The fix restores
the behavior for Issue22320 while keeping all Issue29141 scenarios
working correctly.
-Added !OperatingSystem.IsMacCatalyst() to the guard condition in
GetDesiredSize, restricting the 20pt compensation to real iOS 26+ only —
as intended in the original PR comment.
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for #33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

### Testing related description of change
EditorNoOverlapAfterRotateToLandscape,
EditorNoOverlapAfterRotateToPortrait,
EntryFocusedShouldNotCauseGapAfterRotation Added cropLeft to remove the
navbar on Android and re-saved the image due to entry text changes in
this commit –
8d17a6d,
91047fb.

DrawStringShouldDrawText – The automation ID set to GraphicsView was not
found by Appium on the Windows platform, so a test condition was added
for Windows to take the image directly instead of waiting for the
GraphicsView.

Added the base images for iOS 26 and Mac that were not added previously.

Re-saved the images that failed due to the wrong iOS version image being
added in the PR.

Re-saved the test images that failed due to this fix PR:
#31254 — e.g.,
GraphicsViewFeatureTests and others.
 
Resaved the slider-related test images due to this fix PR —
#34064.

### Issues Fixed




Fixes #34437 



### Tested the behaviour in the following platforms



- [x] iOS
- [x] Mac

---------

Co-authored-by: SyedAbdulAzeem <syedabdulazeem.a@syncfusion.com>
Co-authored-by: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com>
Co-authored-by: TamilarasanSF4853 <tamilarasan.velu@syncfusion.com>
Co-authored-by: LogishaSelvarajSF4525 <logisha.selvaraj@syncfusion.com>
github-actions bot pushed a commit that referenced this pull request Mar 22, 2026
…extending to system navigation bar (#33428)

### Root Cause
In Android `Edge-to-Edge` mode, the `MauiWindowInsetListener` was
applying padding to the root view and consuming bottom insets. This
prevented `BottomNavigationView` from receiving the system navigation
bar insets, so it could not extend its background color into the
navigation bar area—resulting in a visible gap between the tab bar and
the screen edge.
 
### Description of Change
When a `TabbedPage` uses `ToolbarPlacement.Bottom`, the fix applies
bottom padding to `contentView` (the fragment container) instead of the
root view, and passes bottom insets through without consuming them. This
allows `BottomNavigationView` to receive the insets and extend its
background color into the system navigation bar area, eliminating the
gap.

### Issues Fixed
Fixes #33344 
 
Tested the behaviour in the following platforms
- [x] Android
- [ ] Windows
- [x] iOS
- [ ] Mac

**Note:**
This issue is Android-specific. Windows and macOS do not have a system
navigation bar area at the bottom of the screen.

### Screenshots
| Before Issue Fix | After Issue Fix |
|------------------|-----------------|
| <img width="350" alt="withoutfix"
src="https://github.com/user-attachments/assets/878a0361-c0cd-4621-a063-94bbc757d15c"
/> | <img width="350" alt="withfix"
src="https://github.com/user-attachments/assets/ed552f1e-d75f-4275-856a-b8bf993a0dcd"
/> |
github-actions bot pushed a commit that referenced this pull request Mar 22, 2026
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### RootCause of the issue

- In PR #33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for #33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state.
 
### Description of Change
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for #33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

### Test failures
- EntryScrollTest, HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape,
VerifyBindableLayoutWithGridItemTemplate - (EntryScrollTest)Test fails
due to #33428 this PR



### Issues Fixed

Fixes #34509
github-actions bot pushed a commit that referenced this pull request Mar 22, 2026
### Root Cause of the issue



- The failing test: `SetVisibility(Visibility.Collapsed)` device test on
iOS.

  Why it fails: PR #28983's fix maps Visibility → MapIsRunning in
  ActivityIndicatorHandler, which bypasses the standard
ViewExtensions.UpdateVisibility path. The standard path calls Collapse()
to
add a CollapseConstraint (an NSLayoutConstraint that zeros the view's
size).
The PR's UpdateIsRunning only sets Hidden = true — it never calls
Collapse()
- Crash in the FeatureMatrix Navigation Page Scenario in the iOS 26
PR #34326 added an else block in UpdateBarTextColor() that explicitly
sets BackButtonAppearance = null, BackIndicatorImage = null, and
BackIndicatorTransitionMaskImage = null on the navigation bar when no
custom color is applied. On iOS versions before 26, assigning null to
these properties was treated as "use system defaults." On iOS 26, the
Liquid Glass rendering pipeline reads these properties during push/pop
navigation transitions and throws an exception when it encounters an
explicit null — it expects either an unset property or a valid object.
Since useCustomColor is false by default (no IconColor set), this
crashes on every standard page navigation.
- Setting ThumbTintList = null in the else block removes the tint
entirely, causing the thumb to appear white instead of the default blue,
because SwitchCompat does not re-resolve its theme colors once the tint
list is cleared.
- SetAdjustViewBounds(false) was being applied to all images regardless
of their Aspect value. When this property is false, Android’s ImageView
does not resize itself based on the image’s intrinsic aspect ratio and
instead expands to fill the available space. As a result, an Image
control with the default AspectFit setting ignored its height constraint
and overflowed its container, causing the image to appear taller than
expected in the screenshot test.(LoadAndVerifyGif, ThemeRelated feature
tests)
- PR #29144 changed the group-detection guard in ObservableGroupedSource
(iOS and Android) from is IEnumerable to is ICollection to prevent
strings (which implement IEnumerable<char>) from being treated as
groups.
While the intent was correct, the change was too broad. Custom group
types that implement only IEnumerable<T> were also excluded. As a
result, _groupCount became zero on iOS and _groups remained empty on
Android, causing grouped CollectionView rendering failures and
IndexOutOfRangeException during Add/Remove operations.
- StepperHandler.iOS.cs compiles for both iOS and Mac Catalyst. On Mac
Catalyst / macOS 26, OperatingSystem.IsIOS() and IsIOSVersionAtLeast(26)
both return true, and the screen is always landscape. As a result, the
20pt glass pill compensation was incorrectly applied, inflating
GetDesiredSize(1,1) to width = 21. (Native View Bounding Box is not
empty - device Test failures)
- In PR #33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for #33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state. (EntryScrollTest,
HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape and so on failures)

### Description of Change



- Handles the three Visibility cases the same way as
ViewExtensions.UpdateVisibility:

`Visible`: Calls Inflate() (restores layout size) and sets Hidden =
false — identical to UpdateVisibility. Additionally starts/stops the
animation based on IsRunning.
`Hidden`: Calls Inflate() (preserves layout space) and sets Hidden =
true — identical to UpdateVisibility. The indicator keeps its layout
footprint but is invisible.
`Collapsed`: Sets Hidden = true and calls Collapse() (zeros out layout
size via constraints) — identical to UpdateVisibility. The indicator is
both invisible and takes up no space.
- Removed the else block entirely. When no custom color is applied,
these properties should remain untouched. The system defaults work
correctly on their own — there is no need to explicitly reset them to
null
- Removed the else block from UpdateThumbColor in SwitchExtensions.cs.
The default thumb color is managed by SwitchCompat internally from the
Material theme, so no explicit reset is needed.
- Restored the correct logic in ImageViewExtensions.UpdateAspect to call
SetAdjustViewBounds based on the image’s Aspect value:
- The guard has been updated from is ICollection to is IEnumerable &&
not string in the ObservableGroupedSource implementations for both iOS
and Android (GroupsCount(), UpdateGroupTracking(), Add(), Remove()).
This change specifically excludes string while allowing legitimate
custom group types that implement only IEnumerable<T>. The fix restores
the behavior for Issue22320 while keeping all Issue29141 scenarios
working correctly.
-Added !OperatingSystem.IsMacCatalyst() to the guard condition in
GetDesiredSize, restricting the 20pt compensation to real iOS 26+ only —
as intended in the original PR comment.
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for #33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

### Testing related description of change
EditorNoOverlapAfterRotateToLandscape,
EditorNoOverlapAfterRotateToPortrait,
EntryFocusedShouldNotCauseGapAfterRotation Added cropLeft to remove the
navbar on Android and re-saved the image due to entry text changes in
this commit –
8d17a6d,
91047fb.

DrawStringShouldDrawText – The automation ID set to GraphicsView was not
found by Appium on the Windows platform, so a test condition was added
for Windows to take the image directly instead of waiting for the
GraphicsView.

Added the base images for iOS 26 and Mac that were not added previously.

Re-saved the images that failed due to the wrong iOS version image being
added in the PR.

Re-saved the test images that failed due to this fix PR:
#31254 — e.g.,
GraphicsViewFeatureTests and others.
 
Resaved the slider-related test images due to this fix PR —
#34064.

### Issues Fixed




Fixes #34437 



### Tested the behaviour in the following platforms



- [x] iOS
- [x] Mac

---------

Co-authored-by: SyedAbdulAzeem <syedabdulazeem.a@syncfusion.com>
Co-authored-by: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com>
Co-authored-by: TamilarasanSF4853 <tamilarasan.velu@syncfusion.com>
Co-authored-by: LogishaSelvarajSF4525 <logisha.selvaraj@syncfusion.com>
KarthikRajaKalaimani pushed a commit to KarthikRajaKalaimani/maui that referenced this pull request Mar 23, 2026
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### RootCause of the issue

- In PR dotnet#33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for dotnet#33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state.
 
### Description of Change
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for dotnet#33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

### Test failures
- EntryScrollTest, HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape,
VerifyBindableLayoutWithGridItemTemplate - (EntryScrollTest)Test fails
due to dotnet#33428 this PR



### Issues Fixed

Fixes dotnet#34509
KarthikRajaKalaimani pushed a commit to KarthikRajaKalaimani/maui that referenced this pull request Mar 23, 2026
- The failing test: `SetVisibility(Visibility.Collapsed)` device test on
iOS.

  Why it fails: PR dotnet#28983's fix maps Visibility → MapIsRunning in
  ActivityIndicatorHandler, which bypasses the standard
ViewExtensions.UpdateVisibility path. The standard path calls Collapse()
to
add a CollapseConstraint (an NSLayoutConstraint that zeros the view's
size).
The PR's UpdateIsRunning only sets Hidden = true — it never calls
Collapse()
- Crash in the FeatureMatrix Navigation Page Scenario in the iOS 26
PR dotnet#34326 added an else block in UpdateBarTextColor() that explicitly
sets BackButtonAppearance = null, BackIndicatorImage = null, and
BackIndicatorTransitionMaskImage = null on the navigation bar when no
custom color is applied. On iOS versions before 26, assigning null to
these properties was treated as "use system defaults." On iOS 26, the
Liquid Glass rendering pipeline reads these properties during push/pop
navigation transitions and throws an exception when it encounters an
explicit null — it expects either an unset property or a valid object.
Since useCustomColor is false by default (no IconColor set), this
crashes on every standard page navigation.
- Setting ThumbTintList = null in the else block removes the tint
entirely, causing the thumb to appear white instead of the default blue,
because SwitchCompat does not re-resolve its theme colors once the tint
list is cleared.
- SetAdjustViewBounds(false) was being applied to all images regardless
of their Aspect value. When this property is false, Android’s ImageView
does not resize itself based on the image’s intrinsic aspect ratio and
instead expands to fill the available space. As a result, an Image
control with the default AspectFit setting ignored its height constraint
and overflowed its container, causing the image to appear taller than
expected in the screenshot test.(LoadAndVerifyGif, ThemeRelated feature
tests)
- PR dotnet#29144 changed the group-detection guard in ObservableGroupedSource
(iOS and Android) from is IEnumerable to is ICollection to prevent
strings (which implement IEnumerable<char>) from being treated as
groups.
While the intent was correct, the change was too broad. Custom group
types that implement only IEnumerable<T> were also excluded. As a
result, _groupCount became zero on iOS and _groups remained empty on
Android, causing grouped CollectionView rendering failures and
IndexOutOfRangeException during Add/Remove operations.
- StepperHandler.iOS.cs compiles for both iOS and Mac Catalyst. On Mac
Catalyst / macOS 26, OperatingSystem.IsIOS() and IsIOSVersionAtLeast(26)
both return true, and the screen is always landscape. As a result, the
20pt glass pill compensation was incorrectly applied, inflating
GetDesiredSize(1,1) to width = 21. (Native View Bounding Box is not
empty - device Test failures)
- In PR dotnet#33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for dotnet#33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state. (EntryScrollTest,
HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape and so on failures)

- Handles the three Visibility cases the same way as
ViewExtensions.UpdateVisibility:

`Visible`: Calls Inflate() (restores layout size) and sets Hidden =
false — identical to UpdateVisibility. Additionally starts/stops the
animation based on IsRunning.
`Hidden`: Calls Inflate() (preserves layout space) and sets Hidden =
true — identical to UpdateVisibility. The indicator keeps its layout
footprint but is invisible.
`Collapsed`: Sets Hidden = true and calls Collapse() (zeros out layout
size via constraints) — identical to UpdateVisibility. The indicator is
both invisible and takes up no space.
- Removed the else block entirely. When no custom color is applied,
these properties should remain untouched. The system defaults work
correctly on their own — there is no need to explicitly reset them to
null
- Removed the else block from UpdateThumbColor in SwitchExtensions.cs.
The default thumb color is managed by SwitchCompat internally from the
Material theme, so no explicit reset is needed.
- Restored the correct logic in ImageViewExtensions.UpdateAspect to call
SetAdjustViewBounds based on the image’s Aspect value:
- The guard has been updated from is ICollection to is IEnumerable &&
not string in the ObservableGroupedSource implementations for both iOS
and Android (GroupsCount(), UpdateGroupTracking(), Add(), Remove()).
This change specifically excludes string while allowing legitimate
custom group types that implement only IEnumerable<T>. The fix restores
the behavior for Issue22320 while keeping all Issue29141 scenarios
working correctly.
-Added !OperatingSystem.IsMacCatalyst() to the guard condition in
GetDesiredSize, restricting the 20pt compensation to real iOS 26+ only —
as intended in the original PR comment.
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for dotnet#33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

EditorNoOverlapAfterRotateToLandscape,
EditorNoOverlapAfterRotateToPortrait,
EntryFocusedShouldNotCauseGapAfterRotation Added cropLeft to remove the
navbar on Android and re-saved the image due to entry text changes in
this commit –
dotnet@8d17a6d,
dotnet@91047fb.

DrawStringShouldDrawText – The automation ID set to GraphicsView was not
found by Appium on the Windows platform, so a test condition was added
for Windows to take the image directly instead of waiting for the
GraphicsView.

Added the base images for iOS 26 and Mac that were not added previously.

Re-saved the images that failed due to the wrong iOS version image being
added in the PR.

Re-saved the test images that failed due to this fix PR:
dotnet#31254 — e.g.,
GraphicsViewFeatureTests and others.

Resaved the slider-related test images due to this fix PR —
dotnet#34064.

Fixes dotnet#34437

- [x] iOS
- [x] Mac

---------

Co-authored-by: SyedAbdulAzeem <syedabdulazeem.a@syncfusion.com>
Co-authored-by: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com>
Co-authored-by: TamilarasanSF4853 <tamilarasan.velu@syncfusion.com>
Co-authored-by: LogishaSelvarajSF4525 <logisha.selvaraj@syncfusion.com>
@kubaflo kubaflo added the s/agent-review-incomplete AI agent could not complete all phases (blocker, timeout, error) label Mar 23, 2026
KarthikRajaKalaimani pushed a commit to KarthikRajaKalaimani/maui that referenced this pull request Mar 24, 2026
<!--
!!!!!!! MAIN IS THE ONLY ACTIVE BRANCH. MAKE SURE THIS PR IS TARGETING
MAIN. !!!!!!!
-->

### RootCause of the issue

- In PR dotnet#33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for dotnet#33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state.
 
### Description of Change
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for dotnet#33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

### Test failures
- EntryScrollTest, HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape,
VerifyBindableLayoutWithGridItemTemplate - (EntryScrollTest)Test fails
due to dotnet#33428 this PR



### Issues Fixed

Fixes dotnet#34509
KarthikRajaKalaimani pushed a commit to KarthikRajaKalaimani/maui that referenced this pull request Mar 24, 2026
- The failing test: `SetVisibility(Visibility.Collapsed)` device test on
iOS.

  Why it fails: PR dotnet#28983's fix maps Visibility → MapIsRunning in
  ActivityIndicatorHandler, which bypasses the standard
ViewExtensions.UpdateVisibility path. The standard path calls Collapse()
to
add a CollapseConstraint (an NSLayoutConstraint that zeros the view's
size).
The PR's UpdateIsRunning only sets Hidden = true — it never calls
Collapse()
- Crash in the FeatureMatrix Navigation Page Scenario in the iOS 26
PR dotnet#34326 added an else block in UpdateBarTextColor() that explicitly
sets BackButtonAppearance = null, BackIndicatorImage = null, and
BackIndicatorTransitionMaskImage = null on the navigation bar when no
custom color is applied. On iOS versions before 26, assigning null to
these properties was treated as "use system defaults." On iOS 26, the
Liquid Glass rendering pipeline reads these properties during push/pop
navigation transitions and throws an exception when it encounters an
explicit null — it expects either an unset property or a valid object.
Since useCustomColor is false by default (no IconColor set), this
crashes on every standard page navigation.
- Setting ThumbTintList = null in the else block removes the tint
entirely, causing the thumb to appear white instead of the default blue,
because SwitchCompat does not re-resolve its theme colors once the tint
list is cleared.
- SetAdjustViewBounds(false) was being applied to all images regardless
of their Aspect value. When this property is false, Android’s ImageView
does not resize itself based on the image’s intrinsic aspect ratio and
instead expands to fill the available space. As a result, an Image
control with the default AspectFit setting ignored its height constraint
and overflowed its container, causing the image to appear taller than
expected in the screenshot test.(LoadAndVerifyGif, ThemeRelated feature
tests)
- PR dotnet#29144 changed the group-detection guard in ObservableGroupedSource
(iOS and Android) from is IEnumerable to is ICollection to prevent
strings (which implement IEnumerable<char>) from being treated as
groups.
While the intent was correct, the change was too broad. Custom group
types that implement only IEnumerable<T> were also excluded. As a
result, _groupCount became zero on iOS and _groups remained empty on
Android, causing grouped CollectionView rendering failures and
IndexOutOfRangeException during Add/Remove operations.
- StepperHandler.iOS.cs compiles for both iOS and Mac Catalyst. On Mac
Catalyst / macOS 26, OperatingSystem.IsIOS() and IsIOSVersionAtLeast(26)
both return true, and the screen is always landscape. As a result, the
20pt glass pill compensation was incorrectly applied, inflating
GetDesiredSize(1,1) to width = 21. (Native View Bounding Box is not
empty - device Test failures)
- In PR dotnet#33428, the WindowInsetsCompat.Builder block in
MauiWindowInsetListener.ApplyDefaultWindowInsets was simplified to
return insets; to standardize inset handling. This change was unrelated
to the actual fix for dotnet#33344, which only required passing the bottom
inset through as unconsumed.
As part of that refactor, top inset consumption was also removed,
changing the prior contract where the top inset was consumed when
appBarHasContent = true. While normal safe-area scenarios worked
correctly, transient layout states (e.g., temporary Height = 0 during
keyboard dismissal, rotation, animation, or dynamic item generation)
triggered a second inset dispatch. In those moments, the top inset
satisfied the overlap condition and was applied to content before
SafeAreaExtensions could normalize it, causing test failures. Bottom
insets did not regress because their overlap condition cannot be met in
the same transient state. (EntryScrollTest,
HorizontalStackLayout_Spacing_WithLandscape,
VerticalStackLayout_Spacing_WithLandscape and so on failures)

- Handles the three Visibility cases the same way as
ViewExtensions.UpdateVisibility:

`Visible`: Calls Inflate() (restores layout size) and sets Hidden =
false — identical to UpdateVisibility. Additionally starts/stops the
animation based on IsRunning.
`Hidden`: Calls Inflate() (preserves layout space) and sets Hidden =
true — identical to UpdateVisibility. The indicator keeps its layout
footprint but is invisible.
`Collapsed`: Sets Hidden = true and calls Collapse() (zeros out layout
size via constraints) — identical to UpdateVisibility. The indicator is
both invisible and takes up no space.
- Removed the else block entirely. When no custom color is applied,
these properties should remain untouched. The system defaults work
correctly on their own — there is no need to explicitly reset them to
null
- Removed the else block from UpdateThumbColor in SwitchExtensions.cs.
The default thumb color is managed by SwitchCompat internally from the
Material theme, so no explicit reset is needed.
- Restored the correct logic in ImageViewExtensions.UpdateAspect to call
SetAdjustViewBounds based on the image’s Aspect value:
- The guard has been updated from is ICollection to is IEnumerable &&
not string in the ObservableGroupedSource implementations for both iOS
and Android (GroupsCount(), UpdateGroupTracking(), Add(), Remove()).
This change specifically excludes string while allowing legitimate
custom group types that implement only IEnumerable<T>. The fix restores
the behavior for Issue22320 while keeping all Issue29141 scenarios
working correctly.
-Added !OperatingSystem.IsMacCatalyst() to the guard condition in
GetDesiredSize, restricting the 20pt compensation to real iOS 26+ only —
as intended in the original PR comment.
- Restored the original behavior by consuming the top inset when
appBarHasContent = true, while continuing to pass the bottom inset
through unconsumed (the only change required for dotnet#33344). This retains
the Android edge-to-edge fix and restores deterministic safe-area
handling.

EditorNoOverlapAfterRotateToLandscape,
EditorNoOverlapAfterRotateToPortrait,
EntryFocusedShouldNotCauseGapAfterRotation Added cropLeft to remove the
navbar on Android and re-saved the image due to entry text changes in
this commit –
dotnet@8d17a6d,
dotnet@91047fb.

DrawStringShouldDrawText – The automation ID set to GraphicsView was not
found by Appium on the Windows platform, so a test condition was added
for Windows to take the image directly instead of waiting for the
GraphicsView.

Added the base images for iOS 26 and Mac that were not added previously.

Re-saved the images that failed due to the wrong iOS version image being
added in the PR.

Re-saved the test images that failed due to this fix PR:
dotnet#31254 — e.g.,
GraphicsViewFeatureTests and others.

Resaved the slider-related test images due to this fix PR —
dotnet#34064.

Fixes dotnet#34437

- [x] iOS
- [x] Mac

---------

Co-authored-by: SyedAbdulAzeem <syedabdulazeem.a@syncfusion.com>
Co-authored-by: Vignesh-SF3580 <102575140+Vignesh-SF3580@users.noreply.github.com>
Co-authored-by: TamilarasanSF4853 <tamilarasan.velu@syncfusion.com>
Co-authored-by: LogishaSelvarajSF4525 <logisha.selvaraj@syncfusion.com>
PureWeen added a commit that referenced this pull request Mar 24, 2026
## What's Coming

.NET MAUI inflight/candidate introduces significant improvements across
all platforms with focus on quality, performance, and developer
experience. This release includes 66 commits with various improvements,
bug fixes, and enhancements.


## Activityindicator
- [Android] Implemented material3 support for ActivityIndicator by
@Dhivya-SF4094 in #33481
  <details>
  <summary>🔧 Fixes</summary>

- [Implement material3 support for
ActivityIndicator](#33479)
  </details>

- [iOS] Fix: ActivityIndicator IsRunning ignores IsVisible when set to
true by @bhavanesh2001 in #28983
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] [ActivityIndicator] `IsRunning` ignores `IsVisible` when set to
`true`](#28968)
  </details>

## Button
- [iOS] Button RTL text and image overlap - fix by @kubaflo in
#29041

## Checkbox
- [iOS/MacCatalyst] Fix CheckBox foreground color not resetting when set
to null by @Ahamed-Ali in #34284
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Color of the checkBox control is not properly worked on dynamic
scenarios](#34278)
  </details>

## CollectionView
- [iOS] Fix: CollectionView does not clear selection when SelectedItem
is set to null by @Tamilarasan-Paranthaman in
#30420
  <details>
  <summary>🔧 Fixes</summary>

- [CollectionView not being able to remove selected item highlight on
iOS](#30363)
- [[MAUI] Select items traces are
preserved](#26187)
  </details>

- [iOS] CV2 ItemsLayout update by @kubaflo in
#28675
  <details>
  <summary>🔧 Fixes</summary>

- [CollectionView CollectionViewHandler2 doesnt change ItemsLayout on
DataTrigger](#28656)
- [iOS CollectionView doesn't respect a change to ItemsLayout when using
Items2.CollectionViewHandler2](#31259)
  </details>

- [iOS][CV2] Fix CollectionView renders large empty space at bottom of
view by @devanathan-vaithiyanathan in
#31215
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] [MacCatalyst] CollectionView renders large empty space at
bottom of view](#17799)
- [[iOS/Mac] CollectionView2 EmptyView takes up large horizontal space
even when the content is
small](#33201)
  </details>

- [iOS] Fixed issue where group Header/Footer template was set to all
items when IsGrouped was true for an ObservableCollection by
@Tamilarasan-Paranthaman in #29144
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Group Header/Footer Repeated for All Items When IsGrouped is
True for ObservableCollection in
CollectionView](#29141)
  </details>

- [Android] Fix CollectionView selection crash with HeaderTemplate by
@NirmalKumarYuvaraj in #34275
  <details>
  <summary>🔧 Fixes</summary>

- [[Bug] [Android] System.ArgumentOutOfRangeException: Index was out of
range. Must be non-negative and less than the size of the collection.
Parameter name: index](#34247)
  </details>

## DateTimePicker
- [iOS] Fix TimePicker AM/PM frequently changes when the app is closed
and reopened by @devanathan-vaithiyanathan in
#31066
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] TimePicker AM/PM frequently changes when the app is closed and
reopened](#30837)
- [Maui 10 iOS TimePicker Strange Characters in place of
AM/PM](#33722)
  </details>

- Android TimePicker ignores 24 hour system setting when using Format
Property - fix by @kubaflo in #28797
  <details>
  <summary>🔧 Fixes</summary>

- [Android TimePicker ignores 24 hour system setting when using Format
Property](#28784)
  </details>

## Drawing
- [iOS, Mac, Windows] GraphicsView: Fix Background/BackgroundColor not
updating by @NirmalKumarYuvaraj in
#31254
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS, Mac, Windows] GraphicsView does not change the
Background/BackgroundColor](#31239)
  </details>

- [iOS] GraphicsView DrawString - fix by @kubaflo in
#26304
  <details>
  <summary>🔧 Fixes</summary>

- [DrawString not rendering in
iOS.](#24450)
- [GraphicsView DrawString not rendering in
iOS](#8486)
- [DrawString doesn't work on
maccatalyst](#4993)
  </details>

- [Android] - Fix Shadow Rendering For Transparent Fill, Stroke (Lines),
and Text on Shapes by @prakashKannanSf3972 in
#29528
  <details>
  <summary>🔧 Fixes</summary>

- [Ellipse Transparency Not Rendered When Drawing Arc Inside the Ellipse
Using GraphicsView on
Android](#29394)
  </details>

- Revert "[iOS, Mac, Windows] GraphicsView: Fix
Background/BackgroundColor not updating (#31254)" by @Ahamed-Ali via
@Copilot in #34508

## Entry
- [iOS 26] Fix Entry MaxLength not enforced due to new multi-range
delegate by @kubaflo in #32045
  <details>
  <summary>🔧 Fixes</summary>

- [iOS 26 - The MaxLength property value is not respected on an Entry
control.](#32016)
- [.NET MAUI Entry Maximum Length not working on iOS and
macOS](#33316)
  </details>

- [iOS] Fixed Entry with IsPassword toggling loses previously entered
text by @SubhikshaSf4851 in #30572
  <details>
  <summary>🔧 Fixes</summary>

- [Entry with IsPassword toggling loses previously entered text on iOS
when IsPassword is
re-enabled](#30085)
  </details>

## Essentials
- Fix for FilePicker PickMultipleAsync nullable reference type by
@SuthiYuvaraj in #33163
  <details>
  <summary>🔧 Fixes</summary>

- [FilePicker PickMultipleAsync nullable reference
type](#33114)
  </details>

- Replace deprecated NetworkReachability with NWPathMonitor on iOS/macOS
by @jfversluis via @Copilot in #32354
  <details>
  <summary>🔧 Fixes</summary>

- [NetworkReachability is obsolete on iOS/maccatalyst
17.4+](#32312)
- [Use NWPathMonitor on iOS for Essentials
Connectivity](#2574)
  </details>

## Essentials Connectivity
- Update Android Connectivity implementation to use modern APIs by
@jfversluis via @Copilot in #30348
  <details>
  <summary>🔧 Fixes</summary>

- [Update the Android Connectivity implementation to user modern
APIs](#30347)
  </details>

## Flyout
- [iOS] Fixed Flyout icon not updating when root page changes using
InsertPageBefore by @Vignesh-SF3580 in
#29924
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Flyout icon not replaced by back button when root page is
changed using
InsertPageBefore](#29921)
  </details>

## Flyoutpage
- [iOS] Flyout Items Not Displayed in RightToLeft FlowDirection in
Landscape - fix by @kubaflo in #26762
  <details>
  <summary>🔧 Fixes</summary>

- [Flyout Items Not Displayed in RightToLeft FlowDirection on iOS in
Landscape Orientation and Hamburger Icon Positioned
Incorrectly](#26726)
  </details>

## Image
- [Android] Implemented Material3 support for Image by @Dhivya-SF4094 in
#33661
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
Image](#33660)
  </details>

## Keyboard
- [iOS] Fix gap at top of view after rotating device while Entry
keyboard is visible by @praveenkumarkarunanithi in
#34328
  <details>
  <summary>🔧 Fixes</summary>

- [Focusing and entering texts on entry control causes a gap at the top
after rotating simulator.](#33407)
  </details>

## Label
- [Android] Support for images inside HTML label by @kubaflo in
#21679
  <details>
  <summary>🔧 Fixes</summary>

- [Label with HTML TextType does not display images on
Android](#21044)
  </details>

- [fix] ContentLabel Moved to a nested class to prevent CS0122 in
external source generators by @SubhikshaSf4851 in
#34514
  <details>
  <summary>🔧 Fixes</summary>

- [[MAUI] Building Maui App with sample content results CS0122
errors.](#34512)
  </details>

## Layout
- Optimize ordering of children in Flex layout by @symbiogenesis in
#21961

- [Android] Fix control size properties not available during Loaded
event by @Vignesh-SF3580 in #31590
  <details>
  <summary>🔧 Fixes</summary>

- [CollectionView on Android does not provide height, width, logical
children once loaded, works fine on
Windows](#14364)
- [Control's Loaded event invokes before calling its measure override
method.](#14160)
  </details>

## Mediapicker
- [iOS/Android] MediaPicker: Fix image orientation when RotateImage=true
by @michalpobuta in #33892
  <details>
  <summary>🔧 Fixes</summary>

- [MediaPicker.PickPhotosAsync does not preserve image
orientation](#32650)
  </details>

## Modal
- [Windows] Fix modal page keyboard focus not shifting to newly opened
modal by @jfversluis in #34212
  <details>
  <summary>🔧 Fixes</summary>

- [Keyboard focus does not shift to a newly opened modal page: Pressing
enter clicks the button on the page beneath the modal
page](#22938)
  </details>

## Navigation
- [iOS26] Apply view margins in title view by @kubaflo in
#32205
  <details>
  <summary>🔧 Fixes</summary>

- [NavigationPage TitleView iOS
26](#32200)
  </details>

- [iOS] System.NullReferenceException at
NavigationRenderer.SetStatusBarStyle() by @kubaflo in
#29564
  <details>
  <summary>🔧 Fixes</summary>

- [System.NullReferenceException at
NavigationRenderer.SetStatusBarStyle()](#29535)
  </details>

- [iOS 26] Fix back button color not applied for NavigationPage by
@Shalini-Ashokan in #34326
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Color not applied to the Back button text or image on iOS
26](#33966)
  </details>

## Picker
- Fix Picker layout on Mac Catalyst 26+ by @kubaflo in
#33146
  <details>
  <summary>🔧 Fixes</summary>

- [[MacOS 26] Text on picker options are not centered on macOS
26.1](#33229)
  </details>

## Progressbar
- [Android] Implemented Material3 support for ProgressBar by
@SyedAbdulAzeemSF4852 in #33926
  <details>
  <summary>🔧 Fixes</summary>

- [Implement Material3 support for
Progressbar](#33925)
  </details>

## RadioButton
- [iOS, Mac] Fix for RadioButton TextColor for plain Content not working
by @HarishwaranVijayakumar in #31940
  <details>
  <summary>🔧 Fixes</summary>

- [RadioButton: TextColor for plain Content not working on
iOS](#18011)
  </details>

- [All Platforms] Fix RadioButton warning when ControlTemplate is set
with View content by @kubaflo in
#33839
  <details>
  <summary>🔧 Fixes</summary>

- [Seeking clarification on RadioButton + ControlTemplate + Content
documentation](#33829)
  </details>

- Visual state change for disabled RadioButton by @kubaflo in
#23471
  <details>
  <summary>🔧 Fixes</summary>

- [RadioButton disabled UI issue -
iOS](#18668)
  </details>

## SafeArea
- [Android] Fix for TabbedPage BottomNavigation BarBackgroundColor not
extending to system navigation bar by @praveenkumarkarunanithi in
#33428
  <details>
  <summary>🔧 Fixes</summary>

- [[Android] TabbedPage BottomNavigation BarBackgroundColor does not
extend to system navigation bar area in Edge-to-Edge
mode](#33344)
  </details>

## ScrollView
- [Android] ScrollView: Fix HorizontalScrollBarVisibility not updating
immediately at runtime by @SubhikshaSf4851 in
#33528
  <details>
  <summary>🔧 Fixes</summary>

- [Runtime Scrollbar visibility not updating correctly on Android and
macOS platforms.](#33400)
  </details>

- Fixed crash when calling ItemsView.ScrollTo on unloaded CollectionView
by @kubaflo in #25444
  <details>
  <summary>🔧 Fixes</summary>

- [App crashes when calling ItemsView.ScrollTo on unloaded
CollectionView](#23014)
  </details>

## Shell
- [Shell] Update logic for iOS large title display in ShellItemRenderer
by @kubaflo in #33246

- [iOS][Shell] Fix navigation lifecycle and back button for More tab (>5
tabs) by @kubaflo in #27932
  <details>
  <summary>🔧 Fixes</summary>

- [OnAppearing and OnNavigatedTo does not work when using extended
Tabbar (tabbar with more than 5 tabs) on
IOS.](#27799)
- [Shell.BackButtonBehavior does not work when using extended Tabbar
(tabbar with more than 5 tabs)on
IOS.](#27800)
- [Shell TabBar More button causes ViewModel command binding
disconnection on back
navigation](#30862)
- [Content page onappearing not firing if tabs are on the more tab on
IOS](#31166)
  </details>

- [iOS 26] Fix tab bar ghosting when navigating from modal to tabbed
Shell content by @SubhikshaSf4851 in
#34254
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] Tab bar ghosting issue on iOS 26 (liquid
glass)](#34143)
  </details>

- Fix for Shell tab visibility not updating when navigating back
multiple pages by @BagavathiPerumal in
#34403
  <details>
  <summary>🔧 Fixes</summary>

- [Changing Shell Tab Visibility when navigating back multiple pages
ignores Shell Tab
Visibility](#33351)
  </details>

- [iOS/Mac] Fixed OnBackButtonPressed not firing for Shell Navigation
Bar Button by @Dhivya-SF4094 in
#34401
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] OnBackButtonPressed not firing for Shell Navigation Bar
button](#34190)
  </details>

## Slider
- [iOS] Fix for Slider ThumbImageSource is not centered properly on iOS
26 by @HarishwaranVijayakumar in
#34019
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS 26] Slider ThumbImageSource is not centered
properly](#33967)
  </details>

- [Android] Fix improper rendering of ThumbimageSource in Slider by
@NirmalKumarYuvaraj in #34064
  <details>
  <summary>🔧 Fixes</summary>

- [[Slider] MAUI Slider thumb image is big on
android](#13258)
  </details>

## Stepper
- [iOS] Fix Stepper layout overlap in landscape on iOS 26 by
@Vignesh-SF3580 in #34325
  <details>
  <summary>🔧 Fixes</summary>

- [[.NET10] D10 - Customize cursor position - Rotating simulator makes
the button and label
overlap](#34273)
  </details>

## SwipeView
- [iOS] SwipeView: Honor FontImageSource.Color in SwipeItem icon by
@kubaflo in #27389
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS] SwipeView: SwipeItem.IconImageSource.FontImageSource color
value not honored](#27377)
  </details>

## Switch
- [Android] Fix Switch thumb shadow missing when ThumbColor is set by
@Shalini-Ashokan in #33960
  <details>
  <summary>🔧 Fixes</summary>

- [Android Switch Control Thumb
Shadow](#19676)
  </details>

## Toolbar
- [iOS/Mac Catalyst 26] Fix Shell.ForegroundColor not applied to
ToolbarItems by @SyedAbdulAzeemSF4852 in
#34085
  <details>
  <summary>🔧 Fixes</summary>

- [[iOS26] Shell.ForegroundColor is not applied to
ToolbarItems](#34083)
  </details>

- [Android] VoiceOver on Toolbar Item by @kubaflo in
#29596
  <details>
  <summary>🔧 Fixes</summary>

- [VoiceOver on Toolbar
Item](#29573)
- [SemanticProperties do not work on
ToolbarItems](#23623)
  </details>


<details>
<summary>🧪 Testing (11)</summary>

- [Testing] Additional Feature Matrix Test Cases for CollectionView by
@TamilarasanSF4853 in #32432
- [Testing] Feature Matrix UITest Cases for VisualStateManager by
@LogishaSelvarajSF4525 in #34146
- [Testing] Feature Matrix UITest Cases for Clip by @TamilarasanSF4853
in #34121
- [Testing] Feature matrix UITest Cases for Map Control by
@HarishKumarSF4517 in #31656
- [Testing] Feature matrix UITest Cases for Visual Transform Control by
@HarishKumarSF4517 in #32799
- [Testing] Feature Matrix UITest Cases for Shell Pages by
@NafeelaNazhir in #33945
- [Testing] Feature Matrix UITest Cases for Triggers by
@HarishKumarSF4517 in #34152
- [Testing] Refactoring Feature Matrix UITest Cases for CheckBox Control
by @LogishaSelvarajSF4525 in #34283
- Resolve UI test Build Sample failures - Candidate March 16 by
@Ahamed-Ali in #34442
- Fix the failures in the Candidate branch- March 16 by @Ahamed-Ali in
#34453
  <details>
  <summary>🔧 Fixes</summary>

  - [March 16th, Candidate](#34437)
  </details>
- Fixed the iOS 18.5 Candidate failures (March 16,2026) by @Ahamed-Ali
in #34593
  <details>
  <summary>🔧 Fixes</summary>

  - [March 16th, Candidate](#34437)
  </details>

</details>

<details>
<summary>📦 Other (2)</summary>

- Fixed candidate test failures caused by PR #33428. by @Ahamed-Ali in
#34515
  <details>
  <summary>🔧 Fixes</summary>

- [[.NET10] On Android, there's a big space at the top for I, M and N2 &
N3](#34509)
  </details>
- Revert "[iOS] Button RTL text and image overlap - fix (#29041)" in
b0497af

</details>

<details>
<summary>📝 Issue References</summary>

Fixes #2574, Fixes #4993, Fixes #8486, Fixes #13258, Fixes #14160, Fixes
#14364, Fixes #17799, Fixes #18011, Fixes #18668, Fixes #19676, Fixes
#21044, Fixes #22938, Fixes #23014, Fixes #23623, Fixes #24450, Fixes
#26187, Fixes #26726, Fixes #27377, Fixes #27799, Fixes #27800, Fixes
#28656, Fixes #28784, Fixes #28968, Fixes #29141, Fixes #29394, Fixes
#29535, Fixes #29573, Fixes #29921, Fixes #30085, Fixes #30347, Fixes
#30363, Fixes #30837, Fixes #30862, Fixes #31166, Fixes #31239, Fixes
#31259, Fixes #32016, Fixes #32200, Fixes #32312, Fixes #32650, Fixes
#33114, Fixes #33201, Fixes #33229, Fixes #33316, Fixes #33344, Fixes
#33351, Fixes #33400, Fixes #33407, Fixes #33479, Fixes #33660, Fixes
#33722, Fixes #33829, Fixes #33925, Fixes #33966, Fixes #33967, Fixes
#34083, Fixes #34143, Fixes #34190, Fixes #34247, Fixes #34273, Fixes
#34278, Fixes #34437, Fixes #34509, Fixes #34512

</details>

**Full Changelog**:
main...inflight/candidate
KarthikRajaKalaimani pushed a commit to KarthikRajaKalaimani/maui that referenced this pull request Mar 30, 2026
…extending to system navigation bar (dotnet#33428)

### Root Cause
In Android `Edge-to-Edge` mode, the `MauiWindowInsetListener` was
applying padding to the root view and consuming bottom insets. This
prevented `BottomNavigationView` from receiving the system navigation
bar insets, so it could not extend its background color into the
navigation bar area—resulting in a visible gap between the tab bar and
the screen edge.
 
### Description of Change
When a `TabbedPage` uses `ToolbarPlacement.Bottom`, the fix applies
bottom padding to `contentView` (the fragment container) instead of the
root view, and passes bottom insets through without consuming them. This
allows `BottomNavigationView` to receive the insets and extend its
background color into the system navigation bar area, eliminating the
gap.

### Issues Fixed
Fixes dotnet#33344 
 
Tested the behaviour in the following platforms
- [x] Android
- [ ] Windows
- [x] iOS
- [ ] Mac

**Note:**
This issue is Android-specific. Windows and macOS do not have a system
navigation bar area at the bottom of the screen.

### Screenshots
| Before Issue Fix | After Issue Fix |
|------------------|-----------------|
| <img width="350" alt="withoutfix"
src="https://github.com/user-attachments/assets/878a0361-c0cd-4621-a063-94bbc757d15c"
/> | <img width="350" alt="withfix"
src="https://github.com/user-attachments/assets/ed552f1e-d75f-4275-856a-b8bf993a0dcd"
/> |
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-safearea Issues/PRs that have to do with the SafeArea functionality community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/android s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-failed AI could not verify tests catch the bug s/agent-review-incomplete AI agent could not complete all phases (blocker, timeout, error) s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Android] TabbedPage BottomNavigation BarBackgroundColor does not extend to system navigation bar area in Edge-to-Edge mode

6 participants