Skip to content

[iOS] Fix gap at top of view after rotating device while Entry keyboard is visible#34328

Merged
kubaflo merged 9 commits intodotnet:inflight/currentfrom
praveenkumarkarunanithi:fix-33407
Mar 10, 2026
Merged

[iOS] Fix gap at top of view after rotating device while Entry keyboard is visible#34328
kubaflo merged 9 commits intodotnet:inflight/currentfrom
praveenkumarkarunanithi:fix-33407

Conversation

@praveenkumarkarunanithi
Copy link
Copy Markdown
Contributor

Root Cause

When the keyboard appears on iOS, MAUI’s keyboard auto-scroll manager records the container view’s position (the “starting origin”) so that it can restore the view to the same position when the keyboard is dismissed. This works correctly during normal keyboard interactions.
However, if the device is rotated while the keyboard is visible, iOS transforms the container view into landscape coordinates before the keyboardWillHide notification is fired. By the time MAUI’s restore logic runs, the container view has already been laid out using landscape dimensions, while the saved origin still corresponds to the portrait orientation. As a result, MAUI animates the view back to this stale portrait Y-coordinate, which is incorrect for the current layout and creates a visible gap between the navigation bar and the page content.

Description of Change

The fix records the container view’s size at the time the keyboard appears, in addition to the existing origin value. When the keyboard is about to be dismissed, the restore logic compares the current container size with the recorded size.
If the sizes differ, it indicates that the device orientation changed while the keyboard was visible. In this case, the restore animation is skipped entirely, allowing iOS to maintain the correct layout for the new orientation.
If the sizes match, the restore animation proceeds as before, ensuring that the existing behavior remains unchanged for normal keyboard interactions.

Issues Fixed

Fixes #33407

Tested the behaviour in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Output Video

Before Issue Fix After Issue Fix
Beforefix1.mov
Afterfix.24.mov

praveenkumarkarunanithi and others added 8 commits March 3, 2026 16:19
…#34317)

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting
artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from
this PR and let us know in a comment if this change resolves your issue.
Thank you!

### Description of Change

Add `darc-*` to the `trigger: branches: include:` section in
`ci-uitests.yml` and `ci-device-tests.yml` so that `maui-pr-uitests` and
`maui-pr-devicetests` automatically run when dotnet-maestro pushes
dependency updates to `darc-*` branches.

Previously, these pipelines required manual `/azp run` comments on every
maestro PR.

### Issues Fixed

N/A - CI improvement

### Files Changed

- `eng/pipelines/ci-uitests.yml` - Added `darc-*` to CI trigger branch
filter
- `eng/pipelines/ci-device-tests.yml` - Added `darc-*` to CI trigger
branch filter

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@github-actions
Copy link
Copy Markdown
Contributor

github-actions bot commented Mar 4, 2026

🚀 Dogfood this PR with:

⚠️ WARNING: Do not do this without first carefully reviewing the code of this PR to satisfy yourself it is safe.

curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 34328

Or

  • Run remotely in PowerShell:
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 34328"

@dotnet-policy-service dotnet-policy-service bot added the partner/syncfusion Issues / PR's with Syncfusion collaboration label Mar 4, 2026
@sheiksyedm sheiksyedm marked this pull request as ready for review March 6, 2026 14:18
Copilot AI review requested due to automatic review settings March 6, 2026 14:18
@sheiksyedm sheiksyedm added this to the .NET 10 SR6 milestone Mar 6, 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

Fixes an iOS keyboard auto-scroll restoration regression where rotating the device while the keyboard is visible can restore the container view to a stale (pre-rotation) origin, leaving a visible gap at the top of the page.

Changes:

  • Record the container view size when the keyboard first appears and skip restore animation when the container size changes before keyboard dismissal (rotation detected).
  • Add a new HostApp issue page (Issue33407) to reproduce the scenario via UI navigation and focused Entry.
  • Add a new Appium-based UI test plus iOS/Android snapshot baselines to validate the layout after rotation + keyboard dismissal.

Reviewed changes

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

Show a summary per file
File Description
src/Core/src/Platform/iOS/KeyboardAutoManagerScroll.cs Tracks container size at keyboard-show time and conditionally skips restore animation when size changes (rotation).
src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33407.cs New UI test that navigates, focuses Entry, rotates, dismisses keyboard, and verifies screenshot.
src/Controls/tests/TestCases.HostApp/Issues/Issue33407.cs New HostApp repro Shell + pages for Issue33407 navigation and Entry focus scenario.
src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/EntryFocusedShouldNotCauseGapAfterRotation.png Adds iOS baseline screenshot for the new UI test.
src/Controls/tests/TestCases.Android.Tests/snapshots/android/EntryFocusedShouldNotCauseGapAfterRotation.png Adds Android baseline screenshot for the new UI test.

Comment on lines +35 to +37
App.SetOrientationLandscape();
Thread.Sleep(2000);

Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

Thread.Sleep(2000) introduces an arbitrary delay and will also fail to compile unless System.Threading is imported (implicit global usings don’t include Thread). Prefer using the screenshot retry mechanisms (e.g., VerifyScreenshot with a retry timeout) and/or an awaited delay with an async test if you truly need to wait for rotation/keyboard animations to settle.

Copilot uses AI. Check for mistakes.
Comment on lines +128 to +145
Text = "1. In the Entry control below, input some text. The test passes if the text is not obscured."
},
new UITestEntry
{
IsPassword = false,
IsCursorVisible = false,
Placeholder = "IsPassword=False",
AutomationId = "Entry1"
},
new Label
{
Text = "2. In the Entry control below, input some text. The test passes if the text is obscured."
},
new UITestEntry
{
IsPassword = true,
IsCursorVisible = false,
Placeholder = "IsPassword=True",
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

The page content/instructions appear to be copied from the Entry “IsPassword” manual test and don’t describe (or visually emphasize) the rotation-gap scenario this issue/test is meant to validate. Consider updating the labels/instructions to reflect the gap-at-top repro/expected behavior so the HostApp page is self-explanatory and the screenshot assertion is easier to interpret during future regressions.

Suggested change
Text = "1. In the Entry control below, input some text. The test passes if the text is not obscured."
},
new UITestEntry
{
IsPassword = false,
IsCursorVisible = false,
Placeholder = "IsPassword=False",
AutomationId = "Entry1"
},
new Label
{
Text = "2. In the Entry control below, input some text. The test passes if the text is obscured."
},
new UITestEntry
{
IsPassword = true,
IsCursorVisible = false,
Placeholder = "IsPassword=True",
Text = "1. Rotate the device between portrait and landscape with the keyboard hidden. The test passes if no extra gap appears at the top of the page above the entries."
},
new UITestEntry
{
IsPassword = false,
IsCursorVisible = false,
Placeholder = "Top gap check (normal entry)",
AutomationId = "Entry1"
},
new Label
{
Text = "2. Tap into each Entry, then rotate the device again. The test passes if no additional top gap appears and both entries remain aligned directly under this text."
},
new UITestEntry
{
IsPassword = true,
IsCursorVisible = false,
Placeholder = "Top gap check (password entry)",

Copilot uses AI. Check for mistakes.
Comment on lines +38 to +42
// Dismiss keyboard before screenshot to avoid cursor flakiness.
App.DismissKeyboard();

VerifyScreenshot();
}
Copy link

Copilot AI Mar 6, 2026

Choose a reason for hiding this comment

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

This test dismisses the keyboard right before taking the screenshot, but the regression is about incorrect restoration during keyboardWillHide after an orientation change. To ensure the test is actually exercising the buggy path, consider explicitly waiting for the keyboard-dismiss/restore animation to complete (instead of relying on timing) before asserting the screenshot, otherwise the screenshot could be taken mid-transition and become flaky.

Copilot uses AI. Check for mistakes.
@kubaflo
Copy link
Copy Markdown
Contributor

kubaflo commented Mar 7, 2026

🤖 AI Summary

📊 Expand Full Review
🔍 Pre-Flight — Context & Validation
📝 Review SessionAddress review feedback: fix test flakiness and update HostApp instructions · 8d17a6d

Issue: #33407 - Focusing and entering texts on entry control causes a gap at the top after rotating simulator.
PR: #34328 - [iOS] Fix gap at top of view after rotating device while Entry keyboard is visible
Platforms Affected: iOS only (regression since 9.0.120, not reproducible on 9.0.111)
Labels: platform/ios, area-keyboard, partner/syncfusion, i/regression, s/agent-reviewed, s/agent-suggestions-implemented
Author: praveenkumarkarunanithi

Issue Summary

When a user focuses an Entry control on iOS and then rotates the device while the keyboard is visible, a visible gap appears between the navigation bar and the page content. This is an iOS-only regression introduced in v9.0.120.

Root Cause (per PR description): KeyboardAutoManagerScroll records the container view's origin (TopViewBeginOrigin) when the keyboard appears. When the device rotates while the keyboard is visible, iOS transforms the container view into landscape coordinates before keyboardWillHide fires. RestorePosition() then animates the view back to the stale portrait Y-coordinate, creating a visible gap.

Prior Review Context

This PR had a prior agent review at commit 17f3a22. The previous recommendation was REQUEST CHANGES due to:

  1. Thread.Sleep(2000) in test (prohibited by project conventions)
  2. HostApp page had wrong instructions (copy-pasted from IsPassword test)
  3. Missing mandatory NOTE block in PR description

The label s/agent-suggestions-implemented indicates the author addressed review feedback. Current commit 8d17a6d5 addresses items 1 and 2 but the NOTE block status needs verification.

Files Changed

Fix Files:

  • src/Core/src/Platform/iOS/KeyboardAutoManagerScroll.cs (+21, -4) - Core platform fix (UNCHANGED since previous Gate pass)

Test Files:

  • src/Controls/tests/TestCases.HostApp/Issues/Issue33407.cs (+151) - HostApp repro page (updated instructions)
  • src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33407.cs (+44) - UI test (Thread.Sleep → retryTimeout)
  • src/Controls/tests/TestCases.iOS.Tests/snapshots/ios/EntryFocusedShouldNotCauseGapAfterRotation.png - Baseline
  • src/Controls/tests/TestCases.iOS.Tests/snapshots/ios-26/EntryFocusedShouldNotCauseGapAfterRotation.png - Baseline
  • src/Controls/tests/TestCases.Android.Tests/snapshots/android/EntryFocusedShouldNotCauseGapAfterRotation.png - Android baseline

Test Type: UI Tests (Appium/NUnit) - #if IOS || ANDROID guard

Changes Since Previous Gate Pass

Only test/HostApp files changed since Gate passed at 17f3a22:

  • HostApp updated instructions (cosmetic)
  • Test replaced Thread.Sleep(2000) with VerifyScreenshot(retryTimeout: TimeSpan.FromSeconds(2))

The fix file KeyboardAutoManagerScroll.cs was NOT modified.

Reviewer Comments

From Copilot automated review (all now addressed or outdated):

Comment Status
Thread.Sleep(2000) should use retryTimeout ✅ ADDRESSED - now uses VerifyScreenshot(retryTimeout: TimeSpan.FromSeconds(2))
HostApp instructions copied from IsPassword test ✅ ADDRESSED - updated descriptions
Screenshot timing concern after keyboard dismiss ✅ ADDRESSED - retryTimeout handles this

Fix Candidates

# Source Approach Test Result Files Changed Notes
PR PR #34328 Record TopViewBeginContainerSize at keyboard-show; in RestorePosition() skip restore animation if container size changed by >1pt (orientation detection) ✅ PASS (Gate - iOS, prev review) KeyboardAutoManagerScroll.cs (+21/-4) Original PR fix; validated in prior review

🚦 Gate — Test Verification
📝 Review SessionAddress review feedback: fix test flakiness and update HostApp instructions · 8d17a6d

Result: ⚠️ INCONCLUSIVE (Android) / ✅ PASSED (iOS, prior review)
Platform: android (attempted), ios (prior review at unchanged commit)
Mode: Full Verification (RequireFullVerification: true)

Android Gate: ⚠️ BLOCKED (Environment Issue)

Android test run failed due to Android emulator ANR ("System UI isn't responding" dialog), which is a CI infrastructure issue unrelated to the PR code. The emulator's System UI crashed, preventing the gallery from loading, causing a navigation timeout.

  • Tests FAIL without fix on Android: ✅ (but due to emulator ANR, not the fix)
  • Tests FAIL with fix on Android: ✅ (same emulator ANR)
  • Root cause: System UI isn't responding ANR dialog blocking gallery navigation

This is NOT a code issue - it's a known Android CI emulator environment instability.

iOS Gate: ✅ PASSED (Prior Review, Commit Unchanged)

The fix file src/Core/src/Platform/iOS/KeyboardAutoManagerScroll.cs is unchanged since the prior iOS Gate verification at commit 17f3a22:

  • Tests FAIL without fix ✅
  • Tests PASS with fix ✅
  • Validated with: RequireFullVerification: true

Since the fix code is unchanged and only test files were modified since the iOS Gate, the iOS Gate validation remains valid.

Test Filter: Issue33407
Base Branch: main
Fix Files Validated (iOS):

  • src/Core/src/Platform/iOS/KeyboardAutoManagerScroll.cs

🔧 Fix — Analysis & Comparison
📝 Review SessionAddress review feedback: fix test flakiness and update HostApp instructions · 8d17a6d

Fix Exploration: SKIPPED (Environment Blocked)

Reason for skip: Try-fix requires running tests to validate alternatives. Both available paths are blocked:

  1. Android: Emulator ANR ("System UI isn't responding") prevents app navigation
  2. iOS: Not available on current Linux host

Prior Review Fix Candidates (10 attempts from commit 17f3a22)

The prior review at the unchanged fix commit explored 10 independent alternatives:

# Source Approach Test Result Files Changed Notes
1 try-fix Subscribe to UIDeviceOrientationDidChangeNotification; reset TopViewBeginOrigin = InvalidPoint when orientation changes ✅ PASS KeyboardAutoManagerScroll.cs (+17) Adds new observer lifecycle
2 try-fix Save UIInterfaceOrientation at keyboard-show; compare in WillHideKeyboard, invalidate origin if changed ✅ PASS KeyboardAutoManagerScroll.cs (+18) Uses WindowScene.InterfaceOrientation (iOS 13+)
3 try-fix Clamp restored Y to superview bounds origin ❌ FAIL KeyboardAutoManagerScroll.cs Visual diff 5-7%; animation conflicts with UIKit rotation
4 try-fix Refresh TopViewBeginOrigin on second WillKeyboardShow during rotation ❌ FAIL KeyboardAutoManagerScroll.cs Timing issue — rotation fires before new layout settles
5 try-fix Track Window.Bounds.Size at keyboard-show; skip restore if window size changed ✅ PASS KeyboardAutoManagerScroll.cs (+9/-4) Similar pattern to PR but uses window size
6 try-fix Track applied delta (Y shift from keyboard); undo that delta from current Y instead of absolute portrait restore ✅ PASS KeyboardAutoManagerScroll.cs (+15/-8) Rotation-agnostic
7 try-fix Record ContainerView.SafeAreaInsets at keyboard-show; skip restore if insets changed ✅ PASS KeyboardAutoManagerScroll.cs (+6) ⚠️ Early return skips ScrolledView cleanup — latent bug
8 try-fix Use CGAffineTransform translation deltas; reset to identity on hide ✅ PASS KeyboardAutoManagerScroll.cs (+9/-19) Restructures AnimateRootView; more invasive
9 try-fix Compare live container frame size vs superview bounds size in RestorePosition — no saved state needed ✅ PASS KeyboardAutoManagerScroll.cs (+12/-4) Relies on timing assumption about iOS internals
10 try-fix Check ContainerView.Layer.AnimationKeys in RestorePosition; cancel + skip if animations in flight ✅ PASS KeyboardAutoManagerScroll.cs (+13/-3) Relies on Core Animation timing — potentially fragile
PR PR #34328 Record TopViewBeginContainerSize at keyboard-show; in RestorePosition skip if size differs by >1pt ✅ PASS (Gate) KeyboardAutoManagerScroll.cs (+21/-4) Clear, explicit, well-documented, minimal deps

Exhausted: Yes (via prior review)
Selected Fix: PR's fix — simplest, most explicit, no timing dependencies, no latent bugs, proper cleanup


📋 Report — Final Recommendation
📝 Review SessionAddress review feedback: fix test flakiness and update HostApp instructions · 8d17a6d

⚠️ Final Recommendation: REQUEST CHANGES

Summary

PR #34328 fixes a real iOS regression (#33407) where rotating the device while the keyboard is visible causes a gap at the top of the page. The core fix in KeyboardAutoManagerScroll.cs is correct, Gate-validated on iOS, and confirmed by 10 independent fix explorations from the prior review. The author has addressed prior review feedback (Thread.Sleep → retryTimeout, HostApp instructions updated). One required item remains: the mandatory NOTE block is still missing from the PR description.


Root Cause

KeyboardAutoManagerScroll saves TopViewBeginOrigin (the container view's CGPoint) when the keyboard appears. When the device rotates while the keyboard is visible, iOS updates the container view layout to landscape coordinates before UIKeyboardWillHideNotification fires. By the time RestorePosition() runs, the stale portrait Y-origin no longer corresponds to a valid position in the new orientation, causing the view to animate to an incorrect Y and leaving a visible gap above the page content.


Fix Quality: ✅ Correct and Well-Chosen

The PR's approach — recording TopViewBeginContainerSize at keyboard-show and skipping the restore animation when the container size changes — is the simplest, most explicit, and most defensive of all alternatives explored.

8 of 10 independent try-fix alternatives (from prior review) also passed, validating the fix direction. The PR's approach was selected because:

  • No timing dependencies on UIKit internals
  • No invasive signature changes
  • No latent bugs (unlike alternative [Spec] TabView #7 which has an early return that skips ScrolledView cleanup)
  • Minimal footprint with proper cleanup (= CGSize.Empty at end of RestorePosition)

Title & Description Review

Title: [iOS] Fix gap at top of view after rotating device while Entry keyboard is visible — ✅ Accurate, descriptive

Description:

  • ✅ Root Cause section: clear and accurate
  • ✅ Description of Change: accurately describes the size-comparison approach
  • ✅ Issues Fixed: Fixes #33407
  • ✅ Platform checkboxes present
  • Missing mandatory NOTE block — must be prepended per repo conventions

Code Review Findings

🔴 Required Change: Missing NOTE Block

File: PR Description

The mandatory NOTE block is missing from the top of the PR description. This is required for all PRs per repository conventions:

<!-- Please let the below note in for people that find this PR -->
> [!NOTE]
> Are you waiting for the changes in this PR to be merged?
> It would be very helpful if you could [test the resulting artifacts](https://github.com/dotnet/maui/wiki/Testing-PR-Builds) from this PR and let us know in a comment if this change resolves your issue. Thank you!

✅ Implementation Looks Good

  • TopViewBeginContainerSize field added alongside TopViewBeginOrigin — consistent pattern
  • CGSize.Empty used for initialization and cleanup — correct sentinel value
  • 1pt tolerance guard for sub-pixel float drift — well-reasoned and documented
  • Comment clearly explains the rotation detection logic
  • Cleanup at end of RestorePosition() is correct (resets to CGSize.Empty)

✅ Tests Improved

  • Thread.Sleep(2000) replaced with VerifyScreenshot(retryTimeout: TimeSpan.FromSeconds(2))
  • HostApp instructions updated to describe the gap-at-top scenario ✅
  • DismissKeyboard() before screenshot avoids cursor flakiness ✅

Required Changes

  1. Add NOTE block to the top of the PR description (before the existing "### Root Cause" section)

That's the only remaining required change. Once added, the PR is ready to approve.


📋 Expand PR Finalization Review
Title: ✅ Good

Current: [iOS] Fix gap at top of view after rotating device while Entry keyboard is visible

Description: ✅ Excellent

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

When the keyboard appears on iOS, MAUI's keyboard auto-scroll manager records the container view's position (the "starting origin") so that it can restore the view to the same position when the keyboard is dismissed. This works correctly during normal keyboard interactions.
However, if the device is rotated while the keyboard is visible, iOS transforms the container view into landscape coordinates before the keyboardWillHide notification is fired. By the time MAUI's restore logic runs, the container view has already been laid out using landscape dimensions, while the saved origin still corresponds to the portrait orientation. As a result, MAUI animates the view back to this stale portrait Y-coordinate, which is incorrect for the current layout and creates a visible gap between the navigation bar and the page content.

Description of Change

The fix records the container view's size at the time the keyboard appears, in addition to the existing origin value. When the keyboard is about to be dismissed, the restore logic compares the current container size with the recorded size.
If the sizes differ, it indicates that the device orientation changed while the keyboard was visible. In this case, the restore animation is skipped entirely, allowing iOS to maintain the correct layout for the new orientation.
If the sizes match, the restore animation proceeds as before, ensuring that the existing behavior remains unchanged for normal keyboard interactions.

Issues Fixed

Fixes #33407

Tested the behaviour in the following platforms

  • Android
  • Windows
  • iOS
  • Mac

Output Video

Before Issue Fix After Issue Fix
Code Review: ⚠️ Issues Found

Code Review — PR #34328

✅ Looks Good

  • Core fix is correct and minimal. KeyboardAutoManagerScroll.cs adds a single CGSize sentinel field that is recorded when the keyboard appears and compared on dismiss. The change is surgical and does not alter any existing code paths when no orientation change occurs.
  • Normal-case preservation. The if (!sizeChanged) guard ensures the existing restore animation is executed unchanged when orientation has not changed, avoiding any regression risk for the common path.
  • Proper reset/cleanup. TopViewBeginContainerSize is reset to CGSize.Empty in RestorePosition()'s cleanup block alongside the other static state fields, preventing stale state across keyboard appearances.
  • Clear comments. Inline comments in RestorePosition() explain the rationale (stale portrait origin in landscape space) and the reasoning behind the 1pt tolerance, making future maintenance straightforward.
  • Test follows best practices. Uses UITestEntry (cursor-visible = false) to prevent flaky screenshot comparisons due to cursor blink. Uses VerifyScreenshot(retryTimeout: TimeSpan.FromSeconds(2)) instead of Task.Delay(). Has TearDown to reset orientation.
  • Snapshot baselines included. Both ios and ios-26 environment snapshots are committed.

🟡 Suggestions (Low Priority)

1. SizeChangeTolerance should use nfloat or double instead of float

File: src/Core/src/Platform/iOS/KeyboardAutoManagerScroll.cs

const float SizeChangeTolerance = 1.0f;
var sizeChanged = TopViewBeginContainerSize != CGSize.Empty
    && (Math.Abs(currentSize.Width - TopViewBeginContainerSize.Width) > SizeChangeTolerance
        || Math.Abs(currentSize.Height - TopViewBeginContainerSize.Height) > SizeChangeTolerance);

CGSize properties (Width, Height) are nfloat (which is double on 64-bit). The subtraction produces a nfloat, and comparing it against float SizeChangeTolerance involves an implicit widening conversion. This is not a bug — the value 1.0f round-trips to 1.0 as double exactly — but using nfloat or double would be more consistent with the surrounding CoreGraphics API surface and avoids an implicit cast:

const double SizeChangeTolerance = 1.0;

Impact: None (no behavioral difference). Pure style/consistency.


2. HostApp test page navigation is deeper than necessary

File: src/Controls/tests/TestCases.HostApp/Issues/Issue33407.cs

The automated test navigates through three levels of pages (Issue33407 Shell → Issue33407CategoriesPageIssue33407EntryListPageIssue33407E1Page) before reaching the entries being tested. The intermediate category/list pages exist to support potential expansion, but currently there is only one test item (E1).

This makes the test more fragile (more taps required, more navigation state to manage) and the HostApp page more complex than required for the single scenario.

A simpler structure — a flat Shell with a single ContentPage containing the two UITestEntry controls — would be equally effective for the automated test. The more complex structure does have value for manual testing because it better mimics real-world navigation depth (where this bug would be encountered), so it's a trade-off.

Impact: Test reliability (minor). The current structure works and is already committed with snapshot baselines; not a blocking concern.


3. [Issue] attribute specifies PlatformAffected.iOS but test compiles for Android

File: src/Controls/tests/TestCases.HostApp/Issues/Issue33407.cs (line 19) and src/Controls/tests/TestCases.Shared.Tests/Tests/Issues/Issue33407.cs (line 1 #if IOS || ANDROID)

[Issue(IssueTracker.Github, 33407, "...", PlatformAffected.iOS)]
public class Issue33407 : Shell

The [Issue] attribute declares the platform as iOS-only, but the UI test compiles for Android too (via #if IOS || ANDROID). The Android snapshot (EntryFocusedShouldNotCauseGapAfterRotation.png) is committed, confirming Android runs the test. Including Android is fine — it validates that Android doesn't regress — but the PlatformAffected.iOS attribute creates a slight inconsistency.

PlatformAffected.iOS | PlatformAffected.Android would be more accurate, or leave it as PlatformAffected.iOS (the bug only affects iOS) and add a brief comment explaining why the test also runs on Android.

Impact: None (purely informational metadata). Not a blocking concern.


🔴 Critical Issues

None.


@kubaflo kubaflo added s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-reviewed PR was reviewed by AI agent workflow (full 4-phase review) labels Mar 7, 2026
…ctions

- Remove Thread.Sleep(2000) which won't compile without System.Threading
  import and is an anti-pattern for screenshot tests
- Use VerifyScreenshot(retryTimeout:) to properly wait for keyboard-dismiss
  and rotation animations to settle before asserting
- Update HostApp page labels/instructions to describe the rotation-gap
  scenario instead of the copied IsPassword test text
- Update placeholders to reflect the actual test purpose

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
@kubaflo kubaflo added the s/agent-suggestions-implemented Maintainer applies when PR author adopts agent's recommendation label Mar 7, 2026
@kubaflo kubaflo changed the base branch from main to inflight/current March 10, 2026 00:10
@kubaflo kubaflo merged commit 8aeae9a into dotnet:inflight/current Mar 10, 2026
23 of 31 checks passed
PureWeen added a commit that referenced this pull request Mar 11, 2026
…rd is visible (#34328)

### Root Cause
When the keyboard appears on iOS, MAUI’s keyboard auto-scroll manager
records the container view’s position (the “starting origin”) so that it
can restore the view to the same position when the keyboard is
dismissed. This works correctly during normal keyboard interactions.
However, if the device is rotated while the keyboard is visible, iOS
transforms the container view into landscape coordinates before the
`keyboardWillHide` notification is fired. By the time MAUI’s restore
logic runs, the container view has already been laid out using landscape
dimensions, while the saved origin still corresponds to the portrait
orientation. As a result, MAUI animates the view back to this stale
portrait Y-coordinate, which is incorrect for the current layout and
creates a visible gap between the navigation bar and the page content.
 
### Description of Change
The fix records the container view’s size at the time the keyboard
appears, in addition to the existing origin value. When the keyboard is
about to be dismissed, the restore logic compares the current container
size with the recorded size.
If the sizes differ, it indicates that the device orientation changed
while the keyboard was visible. In this case, the restore animation is
skipped entirely, allowing iOS to maintain the correct layout for the
new orientation.
If the sizes match, the restore animation proceeds as before, ensuring
that the existing behavior remains unchanged for normal keyboard
interactions.

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

### Output Video
Before Issue Fix | After Issue Fix |
|----------|----------|
|<video width="40" height="60" alt="Before Fix"
src="https://github.com/user-attachments/assets/5cbfa8db-952e-4380-9f64-1e0d05476e37">|<video
width="50" height="40" alt="After Fix"
src="https://github.com/user-attachments/assets/02e85e9b-8cf6-451e-aa74-1d824c658ff6">|

---------

Co-authored-by: Shane Neuville <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jakub Florkowski <kubaflo123@gmail.com>
github-actions bot added a commit that referenced this pull request Mar 11, 2026
…rd is visible (#34328)

### Root Cause
When the keyboard appears on iOS, MAUI’s keyboard auto-scroll manager
records the container view’s position (the “starting origin”) so that it
can restore the view to the same position when the keyboard is
dismissed. This works correctly during normal keyboard interactions.
However, if the device is rotated while the keyboard is visible, iOS
transforms the container view into landscape coordinates before the
`keyboardWillHide` notification is fired. By the time MAUI’s restore
logic runs, the container view has already been laid out using landscape
dimensions, while the saved origin still corresponds to the portrait
orientation. As a result, MAUI animates the view back to this stale
portrait Y-coordinate, which is incorrect for the current layout and
creates a visible gap between the navigation bar and the page content.
 
### Description of Change
The fix records the container view’s size at the time the keyboard
appears, in addition to the existing origin value. When the keyboard is
about to be dismissed, the restore logic compares the current container
size with the recorded size.
If the sizes differ, it indicates that the device orientation changed
while the keyboard was visible. In this case, the restore animation is
skipped entirely, allowing iOS to maintain the correct layout for the
new orientation.
If the sizes match, the restore animation proceeds as before, ensuring
that the existing behavior remains unchanged for normal keyboard
interactions.

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

### Output Video
Before Issue Fix | After Issue Fix |
|----------|----------|
|<video width="40" height="60" alt="Before Fix"
src="https://github.com/user-attachments/assets/5cbfa8db-952e-4380-9f64-1e0d05476e37">|<video
width="50" height="40" alt="After Fix"
src="https://github.com/user-attachments/assets/02e85e9b-8cf6-451e-aa74-1d824c658ff6">|

---------

Co-authored-by: Shane Neuville <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jakub Florkowski <kubaflo123@gmail.com>
@PureWeen PureWeen mentioned this pull request Mar 17, 2026
PureWeen added a commit that referenced this pull request Mar 19, 2026
…rd is visible (#34328)

### Root Cause
When the keyboard appears on iOS, MAUI’s keyboard auto-scroll manager
records the container view’s position (the “starting origin”) so that it
can restore the view to the same position when the keyboard is
dismissed. This works correctly during normal keyboard interactions.
However, if the device is rotated while the keyboard is visible, iOS
transforms the container view into landscape coordinates before the
`keyboardWillHide` notification is fired. By the time MAUI’s restore
logic runs, the container view has already been laid out using landscape
dimensions, while the saved origin still corresponds to the portrait
orientation. As a result, MAUI animates the view back to this stale
portrait Y-coordinate, which is incorrect for the current layout and
creates a visible gap between the navigation bar and the page content.
 
### Description of Change
The fix records the container view’s size at the time the keyboard
appears, in addition to the existing origin value. When the keyboard is
about to be dismissed, the restore logic compares the current container
size with the recorded size.
If the sizes differ, it indicates that the device orientation changed
while the keyboard was visible. In this case, the restore animation is
skipped entirely, allowing iOS to maintain the correct layout for the
new orientation.
If the sizes match, the restore animation proceeds as before, ensuring
that the existing behavior remains unchanged for normal keyboard
interactions.

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

### Output Video
Before Issue Fix | After Issue Fix |
|----------|----------|
|<video width="40" height="60" alt="Before Fix"
src="https://github.com/user-attachments/assets/5cbfa8db-952e-4380-9f64-1e0d05476e37">|<video
width="50" height="40" alt="After Fix"
src="https://github.com/user-attachments/assets/02e85e9b-8cf6-451e-aa74-1d824c658ff6">|

---------

Co-authored-by: Shane Neuville <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jakub Florkowski <kubaflo123@gmail.com>
github-actions bot added a commit that referenced this pull request Mar 20, 2026
…rd is visible (#34328)

### Root Cause
When the keyboard appears on iOS, MAUI’s keyboard auto-scroll manager
records the container view’s position (the “starting origin”) so that it
can restore the view to the same position when the keyboard is
dismissed. This works correctly during normal keyboard interactions.
However, if the device is rotated while the keyboard is visible, iOS
transforms the container view into landscape coordinates before the
`keyboardWillHide` notification is fired. By the time MAUI’s restore
logic runs, the container view has already been laid out using landscape
dimensions, while the saved origin still corresponds to the portrait
orientation. As a result, MAUI animates the view back to this stale
portrait Y-coordinate, which is incorrect for the current layout and
creates a visible gap between the navigation bar and the page content.
 
### Description of Change
The fix records the container view’s size at the time the keyboard
appears, in addition to the existing origin value. When the keyboard is
about to be dismissed, the restore logic compares the current container
size with the recorded size.
If the sizes differ, it indicates that the device orientation changed
while the keyboard was visible. In this case, the restore animation is
skipped entirely, allowing iOS to maintain the correct layout for the
new orientation.
If the sizes match, the restore animation proceeds as before, ensuring
that the existing behavior remains unchanged for normal keyboard
interactions.

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

### Output Video
Before Issue Fix | After Issue Fix |
|----------|----------|
|<video width="40" height="60" alt="Before Fix"
src="https://github.com/user-attachments/assets/5cbfa8db-952e-4380-9f64-1e0d05476e37">|<video
width="50" height="40" alt="After Fix"
src="https://github.com/user-attachments/assets/02e85e9b-8cf6-451e-aa74-1d824c658ff6">|

---------

Co-authored-by: Shane Neuville <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jakub Florkowski <kubaflo123@gmail.com>
github-actions bot added a commit that referenced this pull request Mar 22, 2026
…rd is visible (#34328)

### Root Cause
When the keyboard appears on iOS, MAUI’s keyboard auto-scroll manager
records the container view’s position (the “starting origin”) so that it
can restore the view to the same position when the keyboard is
dismissed. This works correctly during normal keyboard interactions.
However, if the device is rotated while the keyboard is visible, iOS
transforms the container view into landscape coordinates before the
`keyboardWillHide` notification is fired. By the time MAUI’s restore
logic runs, the container view has already been laid out using landscape
dimensions, while the saved origin still corresponds to the portrait
orientation. As a result, MAUI animates the view back to this stale
portrait Y-coordinate, which is incorrect for the current layout and
creates a visible gap between the navigation bar and the page content.
 
### Description of Change
The fix records the container view’s size at the time the keyboard
appears, in addition to the existing origin value. When the keyboard is
about to be dismissed, the restore logic compares the current container
size with the recorded size.
If the sizes differ, it indicates that the device orientation changed
while the keyboard was visible. In this case, the restore animation is
skipped entirely, allowing iOS to maintain the correct layout for the
new orientation.
If the sizes match, the restore animation proceeds as before, ensuring
that the existing behavior remains unchanged for normal keyboard
interactions.

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

### Output Video
Before Issue Fix | After Issue Fix |
|----------|----------|
|<video width="40" height="60" alt="Before Fix"
src="https://github.com/user-attachments/assets/5cbfa8db-952e-4380-9f64-1e0d05476e37">|<video
width="50" height="40" alt="After Fix"
src="https://github.com/user-attachments/assets/02e85e9b-8cf6-451e-aa74-1d824c658ff6">|

---------

Co-authored-by: Shane Neuville <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jakub Florkowski <kubaflo123@gmail.com>
@karthikraja-arumugam karthikraja-arumugam added the community ✨ Community Contribution label Mar 24, 2026
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
…rd is visible (dotnet#34328)

### Root Cause
When the keyboard appears on iOS, MAUI’s keyboard auto-scroll manager
records the container view’s position (the “starting origin”) so that it
can restore the view to the same position when the keyboard is
dismissed. This works correctly during normal keyboard interactions.
However, if the device is rotated while the keyboard is visible, iOS
transforms the container view into landscape coordinates before the
`keyboardWillHide` notification is fired. By the time MAUI’s restore
logic runs, the container view has already been laid out using landscape
dimensions, while the saved origin still corresponds to the portrait
orientation. As a result, MAUI animates the view back to this stale
portrait Y-coordinate, which is incorrect for the current layout and
creates a visible gap between the navigation bar and the page content.
 
### Description of Change
The fix records the container view’s size at the time the keyboard
appears, in addition to the existing origin value. When the keyboard is
about to be dismissed, the restore logic compares the current container
size with the recorded size.
If the sizes differ, it indicates that the device orientation changed
while the keyboard was visible. In this case, the restore animation is
skipped entirely, allowing iOS to maintain the correct layout for the
new orientation.
If the sizes match, the restore animation proceeds as before, ensuring
that the existing behavior remains unchanged for normal keyboard
interactions.

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

### Output Video
Before Issue Fix | After Issue Fix |
|----------|----------|
|<video width="40" height="60" alt="Before Fix"
src="https://github.com/user-attachments/assets/5cbfa8db-952e-4380-9f64-1e0d05476e37">|<video
width="50" height="40" alt="After Fix"
src="https://github.com/user-attachments/assets/02e85e9b-8cf6-451e-aa74-1d824c658ff6">|

---------

Co-authored-by: Shane Neuville <5375137+PureWeen@users.noreply.github.com>
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: Jakub Florkowski <kubaflo123@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area-keyboard Keyboard, soft keyboard community ✨ Community Contribution partner/syncfusion Issues / PR's with Syncfusion collaboration platform/ios s/agent-changes-requested AI agent recommends changes - found a better alternative or issues s/agent-fix-pr-picked AI could not beat the PR fix - PR is the best among all candidates s/agent-gate-passed AI verified tests catch the bug (fail without fix, pass with fix) 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.

Focusing and entering texts on entry control causes a gap at the top after rotating simulator.

7 participants