Skip to content

Commit 71af14d

Browse files
praveenkumarkarunanithisheiksyedm
authored andcommitted
fix update.
1 parent c4d4f3f commit 71af14d

File tree

2 files changed

+83
-5
lines changed

2 files changed

+83
-5
lines changed

src/Controls/src/Core/Handlers/Items2/iOS/TemplatedCell2.cs

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
using Microsoft.Maui.Controls.Internals;
77
using Microsoft.Maui.Controls.Platform;
88
using Microsoft.Maui.Graphics;
9+
using Microsoft.Maui.Platform;
910
using UIKit;
1011

1112
namespace Microsoft.Maui.Controls.Handlers.Items2
@@ -197,10 +198,71 @@ public override void LayoutSubviews()
197198
// We now have to apply the new bounds size to the virtual view
198199
// which will automatically set the frame on the platform view too.
199200
var frame = new Rect(Point.Zero, boundsSize);
201+
202+
// Inject per-cell safe area insets into the MauiView for CrossPlatformArrange
203+
// to apply as internal padding. UICollectionView bypasses MAUI's arrange chain,
204+
// so cells cannot use the standard safe area flow (#33604, #34635).
205+
if (virtualView is ISafeAreaView2 safeView && PlatformView is MauiView mauiView)
206+
{
207+
var insets = ComputeCellSafeAreaInsets(safeView);
208+
mauiView.CellSafeAreaOverride = insets != UIEdgeInsets.Zero
209+
? insets.ToSafeAreaInsets()
210+
: SafeAreaPadding.Empty;
211+
}
212+
else if (PlatformView is MauiView mv && !mv.CellSafeAreaOverride.IsEmpty)
213+
{
214+
// Clear stale override from a previous template that implemented ISafeAreaView2.
215+
mv.CellSafeAreaOverride = SafeAreaPadding.Empty;
216+
}
217+
200218
virtualView.Arrange(frame);
201219
}
202220
}
203221

222+
/// <summary>
223+
/// Computes per-cell safe area insets based on geometric overlap with the window's unsafe regions.
224+
/// Returns <see cref="UIEdgeInsets.Zero"/> when all edges share the same region (e.g., default
225+
/// Container×4), as the parent layout chain handles uniform safe area (#33604, #34635).
226+
/// </summary>
227+
UIEdgeInsets ComputeCellSafeAreaInsets(ISafeAreaView2 safeView)
228+
{
229+
var window = Window;
230+
if (window is null)
231+
return UIEdgeInsets.Zero;
232+
233+
var windowSA = window.SafeAreaInsets;
234+
if (windowSA == UIEdgeInsets.Zero)
235+
return UIEdgeInsets.Zero;
236+
237+
var leftRegion = safeView.GetSafeAreaRegionsForEdge(0);
238+
var topRegion = safeView.GetSafeAreaRegionsForEdge(1);
239+
var rightRegion = safeView.GetSafeAreaRegionsForEdge(2);
240+
var bottomRegion = safeView.GetSafeAreaRegionsForEdge(3);
241+
242+
// Uniform edges (Container×4, None×4, All×4) are handled by the parent layout chain.
243+
bool allSameRegion = leftRegion == topRegion
244+
&& topRegion == rightRegion
245+
&& rightRegion == bottomRegion;
246+
247+
if (allSameRegion)
248+
return UIEdgeInsets.Zero;
249+
250+
// Only apply insets for Container edges; SoftInput-only edges are excluded.
251+
var cellInWindow = ConvertRectToView(Bounds, window);
252+
var windowBounds = window.Bounds;
253+
254+
nfloat left = SafeAreaEdges.IsContainer(leftRegion) && windowSA.Left > 0
255+
? (nfloat)Math.Max(0, (double)(windowSA.Left - cellInWindow.X)) : 0;
256+
nfloat top = SafeAreaEdges.IsContainer(topRegion) && windowSA.Top > 0
257+
? (nfloat)Math.Max(0, (double)(windowSA.Top - cellInWindow.Y)) : 0;
258+
nfloat right = SafeAreaEdges.IsContainer(rightRegion) && windowSA.Right > 0
259+
? (nfloat)Math.Max(0, (double)(cellInWindow.Right - (windowBounds.Width - windowSA.Right))) : 0;
260+
nfloat bottom = SafeAreaEdges.IsContainer(bottomRegion) && windowSA.Bottom > 0
261+
? (nfloat)Math.Max(0, (double)(cellInWindow.Bottom - (windowBounds.Height - windowSA.Bottom))) : 0;
262+
263+
return new UIEdgeInsets(top, left, bottom, right);
264+
}
265+
204266
public override void PrepareForReuse()
205267
{
206268
//Unbind();

src/Core/src/Platform/iOS/MauiView.cs

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,14 @@ public abstract class MauiView : UIView, ICrossPlatformLayoutBacking, IVisualTre
6262
/// </summary>
6363
bool _appliesSafeAreaAdjustments;
6464

65+
/// <summary>
66+
/// Safe area override injected by TemplatedCell2 for CollectionView cells.
67+
/// UICollectionView bypasses MAUI's arrange chain, so cells cannot use <see cref="_safeArea"/>.
68+
/// Applied as internal padding by <see cref="CrossPlatformArrange"/> and
69+
/// <see cref="CrossPlatformMeasure"/> (#33604, #34635).
70+
/// </summary>
71+
internal SafeAreaPadding CellSafeAreaOverride { get; set; } = SafeAreaPadding.Empty;
72+
6573
// Indicates whether this view should respond to safe area insets.
6674
// Cached to avoid repeated hierarchy checks.
6775
// True if the view is an ISafeAreaView, does not ignore safe area, and is not inside a UIScrollView;
@@ -499,19 +507,23 @@ public ICrossPlatformLayout? CrossPlatformLayout
499507
/// <returns>The desired size of the view</returns>
500508
Size CrossPlatformMeasure(double widthConstraint, double heightConstraint)
501509
{
502-
if (_appliesSafeAreaAdjustments)
510+
var effectiveSafeArea = _appliesSafeAreaAdjustments ? _safeArea
511+
: !CellSafeAreaOverride.IsEmpty ? CellSafeAreaOverride
512+
: SafeAreaPadding.Empty;
513+
514+
if (!effectiveSafeArea.IsEmpty)
503515
{
504516
// When responding to safe area, we need to adjust the constraints to account for the safe area.
505-
widthConstraint -= _safeArea.HorizontalThickness;
506-
heightConstraint -= _safeArea.VerticalThickness;
517+
widthConstraint -= effectiveSafeArea.HorizontalThickness;
518+
heightConstraint -= effectiveSafeArea.VerticalThickness;
507519
}
508520

509521
var crossPlatformSize = CrossPlatformLayout?.CrossPlatformMeasure(widthConstraint, heightConstraint) ?? Size.Zero;
510522

511-
if (_appliesSafeAreaAdjustments)
523+
if (!effectiveSafeArea.IsEmpty)
512524
{
513525
// If we're responding to the safe area, we need to add the safe area back to the size so the container can allocate the correct space
514-
crossPlatformSize = new Size(crossPlatformSize.Width + _safeArea.HorizontalThickness, crossPlatformSize.Height + _safeArea.VerticalThickness);
526+
crossPlatformSize = new Size(crossPlatformSize.Width + effectiveSafeArea.HorizontalThickness, crossPlatformSize.Height + effectiveSafeArea.VerticalThickness);
515527
}
516528

517529
return crossPlatformSize;
@@ -528,6 +540,10 @@ void CrossPlatformArrange(CGRect bounds)
528540
{
529541
bounds = AdjustForSafeArea(bounds);
530542
}
543+
else if (!CellSafeAreaOverride.IsEmpty)
544+
{
545+
bounds = CellSafeAreaOverride.InsetRect(bounds);
546+
}
531547

532548
CrossPlatformLayout?.CrossPlatformArrange(bounds.ToRectangle());
533549
}

0 commit comments

Comments
 (0)