Skip to content

Commit

Permalink
fix(ios): LVI layouting
Browse files Browse the repository at this point in the history
  • Loading branch information
Xiaoy312 committed Feb 12, 2023
1 parent a2d1ce2 commit 16293bb
Show file tree
Hide file tree
Showing 4 changed files with 16 additions and 57 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -37,41 +37,10 @@ public async Task When_GridViewItems_LayoutSlots()
await WindowHelper.WaitForLoaded(gridView);
await WindowHelper.WaitForIdle();

RectAssert.AreEqual(new Rect
{
X = 0d,
Y = 0d,
Width = 104d,
Height = 104d,
},
gvi.LayoutSlot);

RectAssert.AreEqual(new Rect
{
X = 0d,
Y = 0d,
Width = 100d,
Height = 100d,
},
gvi.LayoutSlotWithMarginsAndAlignments);

RectAssert.AreEqual(new Rect
{
X = 104d,
Y = 0d,
Width = 104d,
Height = 104d,
},
gvi2.LayoutSlot);

RectAssert.AreEqual(new Rect
{
X = 104d,
Y = 0d,
Width = 100d,
Height = 100d,
},
gvi2.LayoutSlotWithMarginsAndAlignments);
RectAssert.AreEqual(new Rect(0, 0, 100, 100), gvi.LayoutSlot);
RectAssert.AreEqual(new Rect(0, 0, 100, 100), gvi.LayoutSlotWithMarginsAndAlignments);
RectAssert.AreEqual(new Rect(0, 0, 100, 100), gvi2.LayoutSlot);
RectAssert.AreEqual(new Rect(0, 0, 100, 100), gvi2.LayoutSlotWithMarginsAndAlignments);
}
}
#endif
Expand Down
14 changes: 0 additions & 14 deletions src/Uno.UI/UI/Xaml/Controls/ListViewBase/ListViewBaseSource.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -743,18 +743,6 @@ public ContentControl Content

ContentView.AddSubview(value);

// Calling these methods: Layouter.ArrangeChild() and UpdateContentLayoutSlots()
// everytime we set the Content is required to fix an issue where the
// OS is not triggering the Callback LayoutSubViews() at times making the Children to render
// with the wrong size.
// Layouter.ArrangeChild() will skip if called with the same values.
Layouter.ArrangeChild(value, new Rect(0, 0, (float)Frame.Width, (float)Frame.Height));

// The item has to be arranged relative to this internal container (at 0,0),
// but doing this the LayoutSlot[WithMargins] has been updated,
// so we fakely re-inject the relative position of the item in its parent.
UpdateContentLayoutSlots(Frame);

ClearMeasuredSize();
_contentChangedDisposable.Disposable = value?.RegisterDisposablePropertyChangedCallback(ContentControl.ContentProperty, (_, __) => _measuredContentSize = null);
}
Expand All @@ -781,8 +769,6 @@ public override CGRect Frame
try
{
base.Frame = value;
UpdateContentLayoutSlots(value);

UpdateContentViewFrame();
}
catch
Expand Down
6 changes: 1 addition & 5 deletions src/Uno.UI/UI/Xaml/FrameworkElement.iOS.cs
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,7 @@ public override void LayoutSubviews()

Rect finalRect;
var parent = Superview;
if (parent is UIElement
|| parent is ISetLayoutSlots
// In the case of ListViewItem inside native list, its parent's parent is ListViewBaseInternalContainer
|| parent?.Superview is ISetLayoutSlots
)
if (parent is UIElement or ISetLayoutSlots)
{
finalRect = LayoutSlotWithMarginsAndAlignments;
}
Expand Down
14 changes: 11 additions & 3 deletions src/Uno.UI/UI/Xaml/UIElement.iOS.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
using System;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
Expand Down Expand Up @@ -184,9 +184,17 @@ private bool TryGetParentUIElementForTransformToVisual(out UIElement parentEleme
switch (parent)
{
case ListViewBaseInternalContainer listViewBaseInternalContainer:
// In the case of ListViewBaseInternalContainer, the first managed parent is normally ItemsPresenter. We omit
// the offset since it's incorporated separately via the layout slot propagated to ListViewItem + the scroll offset.
// In the case of ListViewBaseInternalContainer, the first managed parent is normally ItemsPresenter.
// Normally, the offset should be appended in all cases. However with ObservableCollection::Move, it can result in
// the offset to be included in LVI.LayoutSlot already. The if-case guards against that case.
parentElement = listViewBaseInternalContainer.FindFirstParent<UIElement>();
if (listViewBaseInternalContainer.Content is { } container &&
container.LayoutSlot.Left == container.Margin.Left &&
container.LayoutSlot.Top == container.Margin.Top)
{
offsetX += parent.Frame.X;
offsetY += parent.Frame.Y;
}
return true;

case UIElement eltParent:
Expand Down

0 comments on commit 16293bb

Please sign in to comment.