From 16293bb19371dd13fddc944227048e0c4807abb5 Mon Sep 17 00:00:00 2001 From: xiaoy312 Date: Mon, 30 Jan 2023 17:34:44 -0500 Subject: [PATCH] fix(ios): LVI layouting --- .../Given_GridView_Items.cs | 39 ++----------------- .../ListViewBase/ListViewBaseSource.iOS.cs | 14 ------- src/Uno.UI/UI/Xaml/FrameworkElement.iOS.cs | 6 +-- src/Uno.UI/UI/Xaml/UIElement.iOS.cs | 14 +++++-- 4 files changed, 16 insertions(+), 57 deletions(-) diff --git a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_GridView_Items.cs b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_GridView_Items.cs index 2bfd55c6840f..db105a5829cf 100644 --- a/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_GridView_Items.cs +++ b/src/Uno.UI.RuntimeTests/Tests/Windows_UI_Xaml_Controls/Given_GridView_Items.cs @@ -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 diff --git a/src/Uno.UI/UI/Xaml/Controls/ListViewBase/ListViewBaseSource.iOS.cs b/src/Uno.UI/UI/Xaml/Controls/ListViewBase/ListViewBaseSource.iOS.cs index 70893a94d444..6165aa92ec77 100644 --- a/src/Uno.UI/UI/Xaml/Controls/ListViewBase/ListViewBaseSource.iOS.cs +++ b/src/Uno.UI/UI/Xaml/Controls/ListViewBase/ListViewBaseSource.iOS.cs @@ -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); } @@ -781,8 +769,6 @@ public override CGRect Frame try { base.Frame = value; - UpdateContentLayoutSlots(value); - UpdateContentViewFrame(); } catch diff --git a/src/Uno.UI/UI/Xaml/FrameworkElement.iOS.cs b/src/Uno.UI/UI/Xaml/FrameworkElement.iOS.cs index 8906d7bd78e7..0f295c413ef5 100644 --- a/src/Uno.UI/UI/Xaml/FrameworkElement.iOS.cs +++ b/src/Uno.UI/UI/Xaml/FrameworkElement.iOS.cs @@ -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; } diff --git a/src/Uno.UI/UI/Xaml/UIElement.iOS.cs b/src/Uno.UI/UI/Xaml/UIElement.iOS.cs index 1d1704f44d96..dbd2df93a977 100644 --- a/src/Uno.UI/UI/Xaml/UIElement.iOS.cs +++ b/src/Uno.UI/UI/Xaml/UIElement.iOS.cs @@ -1,4 +1,4 @@ -using System; +using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; @@ -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(); + 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: