[Android/iOS] Fix CollectionView not respecting SafeAreaEdges settings#33908
Conversation
There was a problem hiding this comment.
Pull request overview
This PR fixes issue #33604 where CollectionView does not respect SafeAreaEdges settings on individual item templates. The issue manifested differently on Android (regression from 10.0.1 to 10.0.30) and iOS (never worked correctly). The fix enables per-item SafeAreaEdges control within CollectionView/CarouselView items on both platforms.
Changes:
- Android: Removed
IMauiRecyclerViewexclusion from window inset listener lookup, allowing RecyclerView child views (CollectionView items) to receive inset listeners - iOS: Added UICollectionView exception to safe area handling so CollectionView cells can respond to safe area, using Window.SafeAreaInsets to work around iOS notification limitations
Reviewed changes
Copilot reviewed 2 out of 2 changed files in this pull request and generated no comments.
| File | Description |
|---|---|
src/Core/src/Platform/iOS/MauiView.cs |
Added UICollectionView exception in RespondsToSafeArea(), implemented Window.SafeAreaInsets fallback for CollectionView cells, added safe area revalidation logic during orientation changes |
src/Core/src/Platform/Android/MauiWindowInsetListener.cs |
Removed IMauiRecyclerView exclusion from FindListenerForView() to enable per-item SafeAreaEdges control |
874dec3 to
2739829
Compare
kubaflo
left a comment
There was a problem hiding this comment.
Could you please resolve conflicts?
|
🚀 Dogfood this PR with:
curl -fsSL https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.sh | bash -s -- 33908Or
iex "& { $(irm https://raw.githubusercontent.com/dotnet/maui/main/eng/scripts/get-maui-pr.ps1) } 33908" |
Conflicts have been resolved and the branch has been updated accordingly. |
|
/azp run maui-pr-uitests , maui-pr-devicetests |
|
Azure Pipelines successfully started running 2 pipeline(s). |
|
Hi, |
f793dad to
19d3110
Compare
Addressed AI summary review concerns, and added a UI test for CollectionView SafeArea validation (iOS only). |
0bba31b to
627b389
Compare
🤖 AI Summary📊 Expand Full Review —
|
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| PR | PR #33908 | Android: allow RecyclerView item descendants to receive inset listeners. iOS: let UICollectionView descendants participate in safe-area handling and revalidate using window safe-area padding during layout/orientation PENDING (Gate) | MauiWindowInsetListener.cs, MauiView.cs, Issue33604.cs (HostApp/UI test), snapshot |
Original PR plus iOS-only UI regression test | changes. |
🚦 Gate — Test Verification
Gate Result: PASSED
Platform: ios
Mode: Full Verification
- Tests FAIL without fix: yes
- Tests PASS with fix: yes
Evidence
- Used
verify-tests-fail.ps1with-FixFilesoverride to target the PR implementation files despite noisy local diff state. - Verification report:
CustomAgentLogsTmp/PRState/33908/PRAgent/gate/verify-tests-fail/verification-report.md - The report records
Tests WITHOUT fix | FAIL | FAIL | PASSandTests WITH fix | PASS | PASS | PASSforIssue33604on iOS.
🔧 Fix — Analysis & Comparison
Fix Candidates
| # | Source | Approach | Test Result | Files Changed | Notes |
|---|---|---|---|---|---|
| 1 | try-fix (claude-opus-4.6) |
Force CollectionView descendant invalidation in LayoutSubviews() and keep using per-cell SafeAreaInsets instead of window padding. |
FAIL | src/Core/src/Platform/iOS/MauiView.cs |
Functionally closer, but screenshot still differed by 5.88 percent, so it did not match the expected baseline. |
| 2 | try-fix (claude-sonnet-4.6) |
Invalidate CollectionView descendants from TraitCollectionDidChange() while still using Window.SafeAreaInsets. |
PASS | src/Core/src/Platform/iOS/MauiView.cs, src/Core/src/PublicAPI/net-ios/PublicAPI.Unshipped.txt |
Passed the screenshot, but it introduced a new override/API entry and a PublicAPI change, making it heavier than the PR fix. |
| 3 | try-fix (gpt-5.3-codex) |
Propagate safe-area invalidation from ancestor SafeAreaInsetsDidChange() into UICollectionView descendants while relying on collection-parent/cell inset propagation. |
FAIL | src/Core/src/Platform/iOS/MauiView.cs |
Also failed the screenshot by 5.88 percent, reinforcing that ancestor/cell inset propagation alone does not match the expected layout. |
| 4 | try-fix (gemini-3-pro-preview) |
Use a geometric Window.SafeAreaInsets intersection fallback for collection descendants instead of the PR's arrange-time cache/revalidation pattern. |
FAIL | src/Core/src/Platform/iOS/MauiView.cs, src/Controls/tests/TestCases.Shared.Tests/UITest.cs |
Still produced portrait-style/stale inset behavior in the test run and missed the screenshot baseline. |
| 5 | try-fix (gpt-5.3-codex, cross-pollination) |
Hard-disable per-cell safe-area handling for UICollectionViewCell descendants and push compensation to the container chain only. |
FAIL | src/Core/src/Platform/iOS/MauiView.cs, src/Core/src/Platform/iOS/MauiScrollView.cs |
Test command failed before behavioral validation because the local baseline drifted into the known ImageMagick compile mismatch. |
| 6 | try-fix (gemini-3-pro-preview, cross-pollination) |
Enable PreservesSuperviewLayoutMargins on UICollectionViewCell / ContentView to lean on UIKit inset propagation. |
BLOCKED | src/Controls/src/Core/Handlers/Items2/iOS/ItemsViewCell2.cs |
Also blocked by the same local ImageMagick compile drift before the idea could be behaviorally validated. |
| PR | PR #33908 | Distinguish UICollectionView descendants from ordinary UIScrollView descendants, source CollectionView cell safe-area values from Window.SafeAreaInsets, and force revalidation during arrange when window padding changes. |
PASSED (Gate) | src/Core/src/Platform/iOS/MauiView.cs, src/Core/src/Platform/Android/MauiWindowInsetListener.cs, Issue33604 UI test files |
Original PR validated on iOS via full fail-without-fix / pass-with-fix gate verification. |
Cross-Pollination
| Model | Round | New Ideas? | Details |
|---|---|---|---|
| claude-opus-4.6 | 2 | No | NO NEW IDEAS |
| claude-sonnet-4.6 | 2 | No | NO NEW IDEAS |
| gpt-5.3-codex | 2 | Yes | NEW IDEA: For any MauiView/MauiScrollView inside a UICollectionViewCell, hard-disable per-cell safe-area application and apply compensation once at the UICollectionView container level only. |
| gemini-3-pro-preview | 2 | Yes | NEW IDEA: Enable PreservesSuperviewLayoutMargins on the UICollectionViewCell and its ContentView to rely on UIKit's native inset propagation mechanism. |
| claude-opus-4.6 | 3 | No | NO NEW IDEAS |
| claude-sonnet-4.6 | 3 | Yes | NEW IDEA: Drive compensation from the nearest UIViewController's ViewSafeAreaInsetsDidChange / UIViewController.View.SafeAreaInsets. |
| gpt-5.3-codex | 3 | Yes | NEW IDEA: Set ContentInsetAdjustmentBehavior = Never and apply Window safe area via FlowLayout.SectionInset manually. |
| gemini-3-pro-preview | 3 | No | NO NEW IDEAS |
Exhausted: Yes - max 3 cross-pollination rounds reached.
Selected Fix: PR #33908 - It is the simplest passing implementation: validated by full gate verification, avoids the extra PublicAPI/API surface required by Attempt 2, and directly addresses both the stale inset source and invalidation timing problem for CollectionView cells.
📋 Report — Final Recommendation
Final Recommendation: APPROVE
Phase Status
| Phase | Status | Notes |
|---|---|---|
| Pre-Flight | COMPLETE | Issue/PR context, file classification, discussion edge cases, and current check status documented. |
| Gate | PASSED | iOS full verification proved Issue33604 fails without the fix and passes with the fix. |
| Try-Fix | COMPLETE | 6 attempts explored; 1 alternative passed, but it was heavier and expanded API surface compared to the PR fix. |
| Report | COMPLETE |
Summary
PR #33908 fixes the iOS CollectionView safe-area regression by letting UICollectionView descendants participate in safe-area handling, using Window.SafeAreaInsets as the reliable source for CollectionView cell layout, and forcing revalidation when those window insets change. The new iOS UI regression test (Issue33604) correctly catches the bug: it failed without the fix and passed with the fix during gate verification.
Try-fix exploration found only one passing alternative: an event-driven TraitCollectionDidChange() version that still depended on Window.SafeAreaInsets. That alternative added a new override/API surface and required a PublicAPI update, making it less surgical than the PR's existing arrange-time revalidation approach. Other alternatives either consistently missed the screenshot baseline by 5.88 percent or were blocked by local baseline drift in the ImageMagick test dependency.
Root Cause
UICollectionView inherits from UIScrollView, so MAUI's existing iOS safe-area logic treated CollectionView descendants like ordinary scroll-view children and skipped their safe-area participation. On rotation, CollectionView cell content also does not reliably receive fresh per-cell SafeAreaInsets, leaving stale values in the cell subtree. Fixing the bug therefore requires both:
- an exception so CollectionView descendants are allowed to participate in safe-area handling, and
- a reliable source of current safe-area values plus a revalidation trigger when orientation/window insets change.
Fix Quality
The PR's fix is the best candidate from the review:
- It passed full fail-without-fix / pass-with-fix verification on iOS.
- It solves both parts of the root cause: descendant eligibility and stale safe-area values after rotation.
- It is more contained than the only passing alternative because it avoids adding new API/PublicAPI surface.
- The added UI regression test is appropriately scoped to iOS, where notch/cutout behavior is observable and relevant for this bug.
#33908) <!-- 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! ### Root Cause Android: CollectionView uses `RecyclerView` which implements `IMauiRecyclerView`. When individual item views within the ItemTemplate have explicit SafeAreaEdges settings (e.g., `<Grid SafeAreaEdges="Container,None">`), these item views were excluded from receiving window inset listeners because of the `|| view is IMauiRecyclerView` check in `FindListenerForView()`. This prevented per-item safe area control within CollectionView items. iOS: CollectionView uses `UICollectionView`, which inherits from `UIScrollView`. The `RespondsToSafeArea()` check excluded all `UIScrollView` descendants, preventing CollectionView cell content views from responding to safe area. Additionally, cell content views never receive `SafeAreaInsetsDidChange()` notifications during orientation changes, causing their `SafeAreaInsets` property to remain **stale**. ### Description of Change Android: Removed the `|| parent is IMauiRecyclerView` exclusion from `FindListenerForView()`. RecyclerView child views (CollectionView item views) can now receive window inset listeners, enabling `SafeAreaEdges` on individual item templates. iOS: Added an exception in `RespondsToSafeArea()` so that `UICollectionView` descendants respond to safe area even though they inherit from `UIScrollView`. For CollectionView descendants, `Window.SafeAreaInsets` is used instead of `this.SafeAreaInsets` to obtain current safe area values during layout. In `CrossPlatformArrange()`, safe area revalidation is forced when window insets change (such as during orientation changes), ensuring CollectionView cell content views update correctly. ### Issues Fixed Fixes #33604 ### Platforms Tested - [x] iOS - [x] Android - [x] Windows - [x] Mac **Note:** Test scoped to iOS only — Android CI devices lack notch/cutout hardware, so SafeArea screenshot differences are not observable on that platform. ### iOS Screenshots | Before Fix | After Fix | |------------|-----------| | <video width="350" alt="withoutfix" src="https://github.com/user-attachments/assets/466ca15c-db77-45ff-8cfb-2d2042ca3b2d" /> | <video width="350" alt="withfix" src="https://github.com/user-attachments/assets/33f9ea89-a8bd-40c8-b4d8-cb0e7d93348c" /> | ### Android Screenshots | Before Fix | After Fix | |------------|-----------| | <video width="350" alt="withoutfix" src="https://github.com/user-attachments/assets/df310e84-67a7-42cd-adc0-7f91af1a1d36" /> | <video width="350" alt="withfix" src="https://github.com/user-attachments/assets/70c4d21c-5ccc-4492-9bcb-9ee03d6a25c7" /> |
Adds a new skill and gh-aw workflow that detects if a PR modifies or reverts code from a recent bug-fix PR, which could re-introduce a previously-fixed bug. Motivation: Three P/0 regressions (#34634, #34635, #34636) shipped in 10.0.60 because the agent approved PRs that unknowingly reverted lines from prior fix PRs. This skill would have caught them — e.g., PR #33908 removed a line from PR #32278 that fixed #32436, and the exact same bug reappeared. How it works: - For each implementation file in the PR diff, queries git log for recent PRs (6 months) - Checks if those PRs were bug fixes (via PR labels or linked issue labels: i/regression, t/bug, p/0, p/1) - Compares lines ADDED by fix PRs against lines REMOVED by the current PR - Reports revert risks (🔴), overlaps (🟡), or clean (🟢) Triggers: - pull_request: auto on src/**/*.cs or src/**/*.xaml changes - workflow_dispatch: manual — enter PR number - issue_comment: /check-regression on a PR Files: - .github/skills/find-regression-risk/SKILL.md - .github/skills/find-regression-risk/scripts/Find-RegressionRisks.ps1 - .github/workflows/copilot-find-regression-risk.md - .github/workflows/copilot-find-regression-risk.lock.yml - .github/aw/actions-lock.json (updated) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Regression Risk Analysis🟡 Overlaps found — This PR modifies files that were recently changed by bug-fix PRs, but does not revert their fix lines.
📊 Expand Full Analysis
Notes
Note 🔒 Integrity filtering filtered 5 itemsIntegrity filtering activated and filtered the following items during workflow execution.
|
Add a new mandatory regression detection step to the pr-finalize code review workflow that catches PRs which inadvertently revert lines added by prior bug fixes. ## Problem Three P/0 regressions (#34634, #34635, #34636) shipped in 10.0.60 because the agent approved PRs that unknowingly reverted lines from prior fix PRs. Specifically, PR #33908 removed `|| parent is IMauiRecyclerView` from MauiWindowInsetListener.cs — a line PR #32278 added to fix issue #32436 — causing that bug to reappear. The agent's code review had no mechanism to detect this 'reverted fix' pattern. ## Changes ### .github/skills/pr-finalize/SKILL.md - Add "Prior Fix Regression Check" as Step 1 of Phase 2 (Code Review) - Documents the pattern with the real MauiWindowInsetListener.cs example - Specifies what to flag as 🔴 Critical and what to output ### .github/skills/pr-finalize/scripts/Detect-Regressions.ps1 - New PowerShell script that automates regression detection - Gets PR diff, extracts deleted lines from implementation files - Runs git blame to find originating commits - Flags lines whose commit references an issue number (fixes #XXXX) - Exits with code 1 if regressions detected (integrates with CI) ### .github/skills/pr-finalize/tests/eval.yaml - Eval test cases for the pr-finalize skill - Covers: regression detected (should flag), benign removal (should not flag), refactoring commit (should not flag), multiple regressions, general code review ### .github/instructions/regression-detection.instructions.md - Global instruction file documenting the reverted-fix anti-pattern - Explains detection method (git blame on deleted lines) - Lists high-risk MAUI code patterns prone to this issue - Guidance for PR authors on how to document intentional removals ### .github/copilot-instructions.md - Add regression detection step to the Code Review Instructions section Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
dotnet#33908) <!-- 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! ### Root Cause Android: CollectionView uses `RecyclerView` which implements `IMauiRecyclerView`. When individual item views within the ItemTemplate have explicit SafeAreaEdges settings (e.g., `<Grid SafeAreaEdges="Container,None">`), these item views were excluded from receiving window inset listeners because of the `|| view is IMauiRecyclerView` check in `FindListenerForView()`. This prevented per-item safe area control within CollectionView items. iOS: CollectionView uses `UICollectionView`, which inherits from `UIScrollView`. The `RespondsToSafeArea()` check excluded all `UIScrollView` descendants, preventing CollectionView cell content views from responding to safe area. Additionally, cell content views never receive `SafeAreaInsetsDidChange()` notifications during orientation changes, causing their `SafeAreaInsets` property to remain **stale**. ### Description of Change Android: Removed the `|| parent is IMauiRecyclerView` exclusion from `FindListenerForView()`. RecyclerView child views (CollectionView item views) can now receive window inset listeners, enabling `SafeAreaEdges` on individual item templates. iOS: Added an exception in `RespondsToSafeArea()` so that `UICollectionView` descendants respond to safe area even though they inherit from `UIScrollView`. For CollectionView descendants, `Window.SafeAreaInsets` is used instead of `this.SafeAreaInsets` to obtain current safe area values during layout. In `CrossPlatformArrange()`, safe area revalidation is forced when window insets change (such as during orientation changes), ensuring CollectionView cell content views update correctly. ### Issues Fixed Fixes dotnet#33604 ### Platforms Tested - [x] iOS - [x] Android - [x] Windows - [x] Mac **Note:** Test scoped to iOS only — Android CI devices lack notch/cutout hardware, so SafeArea screenshot differences are not observable on that platform. ### iOS Screenshots | Before Fix | After Fix | |------------|-----------| | <video width="350" alt="withoutfix" src="https://github.com/user-attachments/assets/466ca15c-db77-45ff-8cfb-2d2042ca3b2d" /> | <video width="350" alt="withfix" src="https://github.com/user-attachments/assets/33f9ea89-a8bd-40c8-b4d8-cb0e7d93348c" /> | ### Android Screenshots | Before Fix | After Fix | |------------|-----------| | <video width="350" alt="withoutfix" src="https://github.com/user-attachments/assets/df310e84-67a7-42cd-adc0-7f91af1a1d36" /> | <video width="350" alt="withfix" src="https://github.com/user-attachments/assets/70c4d21c-5ccc-4492-9bcb-9ee03d6a25c7" /> |
…candidate branch (#34667) <!-- 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! **Reverts the iOS-specific `Window.SafeAreaInsets` changes that caused CollectionView cell misalignment on the candidate branch from #33908 , and re-implements safe area handling via per-cell geometric overlap computation that works correctly across all platforms.** ### Root Cause **Cause of regression:** PR #33908 introduced the issue by using `Window.SafeAreaInsets` for `CollectionView` cells; on macOS this includes a 41px title bar. Due to a timing race (`IsParentHandlingSafeArea()` returning false), all cells incorrectly applied this inset, causing misalignment. Reverted the iOS changes from PR #33908 in MauiView.cs, restoring the previous behavior. Android changes were retained as they function correctly. **Actual root cause of Issue33604:** PR #33908 modified `MauiView.GetAdjustedSafeAreaInsets()` to use `Window.SafeAreaInsets` as the base safe area for CollectionView cell descendants. On macOS, `Window.SafeAreaInsets.Top` is 41px (title bar). Combined with `IsParentHandlingSafeArea()` returning false due to a timing race (parent not yet validated), every CollectionView cell received `_appliesSafeAreaAdjustments = true` with a 41px top inset, causing all items to be misaligned on MacCatalyst. Fix: Fully reverted all iOS changes from PR #33908 in MauiView.cs, restoring it to the pre-#33908 state. The Android changes from PR #33908 are retained as they work correctly (WindowInsetsCompat propagates to all views regardless of `RecyclerView` containment). ### Description of Change The fix introduces a shared helper in `MauiView` (`ApplyCellSafeAreaOverride` / `ComputeCellSafeAreaInsets`) used by both `TemplatedCell` (CV1) and `TemplatedCell2` (CV2) during `LayoutSubviews`. Before arranging, per-cell safe area insets are computed based on the cell's geometric position relative to the window's unsafe regions and passed via a new `CellSafeAreaOverride` property. The cell frame remains full-width so backgrounds extend edge-to-edge, while content is inset internally. Uniform configurations (`Container×4`, `None×4`, `All×4`) are skipped as they are handled by the parent layout. Insets are applied only for edges explicitly set to `Container` or `All`, and ignored for `SoftInput`-only edges. A tolerance filter (`ToSafeAreaInsets`) avoids sub-pixel layout noise. `MauiView` applies this override during `CrossPlatformMeasure` and `CrossPlatformArrange` when `_appliesSafeAreaAdjustments` is false, treating it as internal padding consistent with existing `AdjustForSafeArea` behavior. Stale overrides are cleared during cell reuse when the template no longer implements `ISafeAreaView2`. Additionally, `ContentInsetsReference` is set to `UIContentInsetsReference.None` at all three section creation sites in `LayoutFactory2` (Linear, Grid, Carousel). On iOS 26.1+, the default (`.automatic` → `.safeArea`) started actively insetting cells at the section level in `UICollectionViewCompositionalLayout`, conflicting with MAUI's internal safe area handling. Setting `.None` restores pre-26.1 behavior. CV1 is unaffected as it uses `UICollectionViewFlowLayout`, which does not have this property. ### Issues Fixed Fixes #33604 Fixes #34635 ### Additional Fixes Also resolves the following Failed iOS test cases: `VerifyGroupFooterTemplate_WithFooterString` `VerifyGroupHeaderTemplate_WithFooterString` `VerifyIsGroupedFalse_WithHeaderAndFooterString` `SelectedItemVisualIsCleared` `CollectionViewItemsShouldRespectSafeAreaEdges` Tested the behaviour in the following platforms - [x] Android - [ ] Windows - [x] iOS - [x] Mac ### Screenshots **Issue33604** | Before Fix | After Fix | |------------|-----------| | <video width="350" alt="withoutfix" src="https://github.com/user-attachments/assets/466ca15c-db77-45ff-8cfb-2d2042ca3b2d" /> | <video width="350" alt="withfix" src="https://github.com/user-attachments/assets/33f9ea89-a8bd-40c8-b4d8-cb0e7d93348c" /> | **Issue34635** | Before Fix | After Fix | |------------|-----------| | <video width="350" alt="withoutfix" src="https://github.com/user-attachments/assets/783cc1ba-f18d-4aa2-8102-2e217f32ccc9" /> | <video width="350" alt="withfix" src="https://github.com/user-attachments/assets/9b6e8107-20d0-4a71-b2b5-3030a2db317c" /> |
Two bugs fixed: 1. .Count failed on non-array returns in strict mode — wrapped Get-IssueReferences calls in @() to ensure array type 2. Script missed regressions where the originating commit only had 'fixes #XXXX' in the PR description, not the commit message. Now when a commit references a PR via (#XXXX) but has no issue refs in its message, the script queries the PR body via gh CLI. Also fixed issue ref formatting in the report (#32301, 32436 → #32301, #32436). Verified: correctly detects PR #33908 removing the IMauiRecyclerView guard that was added by PR #32278 to fix issue #32436. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Adds Prior Fix Regression Check that detects when PRs remove lines that were added by prior bug fixes (e.g. PR #33908 removing a guard added by PR #32278 to fix issue #32436). Files: - copilot-regression-check.md/.lock.yml — gh-aw workflow - Detect-Regressions.ps1 — detection script (checks commit msgs + PR bodies) - eval.yaml — 11 eval scenarios - regression-detection.instructions.md — global instructions - SKILL.md — updated pr-finalize skill with regression check Triggers: pull_request (no paths filter, gate step instead), issue_comment (/check-regressions), workflow_dispatch (pr_number) Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
🔍 Prior Fix Regression CheckResult: ✅ No prior fix regressions detected Checked deleted lines across implementation files. No lines were identified as reversions of prior bug fixes.
|
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
Android:
CollectionView uses
RecyclerViewwhich implementsIMauiRecyclerView. When individual item views within the ItemTemplate have explicit SafeAreaEdges settings (e.g.,<Grid SafeAreaEdges="Container,None">), these item views were excluded from receiving window inset listeners because of the|| view is IMauiRecyclerViewcheck inFindListenerForView(). This prevented per-item safe area control within CollectionView items.iOS:
CollectionView uses
UICollectionView, which inherits fromUIScrollView. TheRespondsToSafeArea()check excluded allUIScrollViewdescendants, preventing CollectionView cell content views from responding to safe area. Additionally, cell content views never receiveSafeAreaInsetsDidChange()notifications during orientation changes, causing theirSafeAreaInsetsproperty to remain stale.Description of Change
Android:
Removed the
|| parent is IMauiRecyclerViewexclusion fromFindListenerForView(). RecyclerView child views (CollectionView item views) can now receive window inset listeners, enablingSafeAreaEdgeson individual item templates.iOS:
Added an exception in
RespondsToSafeArea()so thatUICollectionViewdescendants respond to safe area even though they inherit fromUIScrollView. For CollectionView descendants,Window.SafeAreaInsetsis used instead ofthis.SafeAreaInsetsto obtain current safe area values during layout. InCrossPlatformArrange(), safe area revalidation is forced when window insets change (such as during orientation changes), ensuring CollectionView cell content views update correctly.Issues Fixed
Fixes #33604
Platforms Tested
Note: Test scoped to iOS only — Android CI devices lack notch/cutout hardware, so SafeArea screenshot differences are not observable on that platform.
iOS Screenshots
iOS-withoutfix.1.mov
iOS-withfix.1.mov
Android Screenshots
Android-withoutfix.mov
Android-withfix.mov