Skip to content

Commit 9bcd9d8

Browse files
fix(scrollviewer): [iOS] Ensure ScrollViewer.ViewportWidth is updated correctly
Accounts for asynchronous arrange pass on iOS.
1 parent 49d3185 commit 9bcd9d8

File tree

2 files changed

+21
-8
lines changed

2 files changed

+21
-8
lines changed

src/Uno.UI/UI/Xaml/Controls/ScrollContentPresenter/NativeScrollContentPresenter.iOS.cs

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,12 @@ partial class NativeScrollContentPresenter : UIScrollView, DependencyObject
3333
internal NativeScrollContentPresenter(ScrollViewer scroller) : this()
3434
{
3535
_scrollViewer = new WeakReference<ScrollViewer>(scroller);
36+
37+
// Because the arrange pass is asynchronous on iOS, this is required for the ScrollViewer to get up-to-date viewport dimensions
38+
SizeChanged += (_, __) =>
39+
{
40+
GetParentScrollViewer()?.UpdateDimensionProperties();
41+
};
3642
}
3743

3844
public NativeScrollContentPresenter()
@@ -61,7 +67,7 @@ private void OnScrolled(object sender, EventArgs e)
6167

6268
private void InvokeOnScroll()
6369
{
64-
var scroller = _scrollViewer.TryGetTarget(out var s) ? s : TemplatedParent as ScrollViewer;
70+
var scroller = GetParentScrollViewer();
6571
if (scroller is null)
6672
{
6773
return;
@@ -74,6 +80,8 @@ private void InvokeOnScroll()
7480
scroller.OnScrollInternal(clampedOffset.X, clampedOffset.Y, isIntermediate: _isInAnimatedScroll);
7581
}
7682

83+
private ScrollViewer GetParentScrollViewer() => _scrollViewer.TryGetTarget(out var s) ? s : TemplatedParent as ScrollViewer;
84+
7785
// Called when user starts dragging
7886
private void OnDraggingStarted(object sender, EventArgs e)
7987
{

src/Uno.UI/UI/Xaml/Controls/ScrollViewer/ScrollViewer.cs

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,12 @@ internal override void OnLayoutUpdated()
652652
UpdateZoomedContentAlignment();
653653
}
654654

655-
private void UpdateDimensionProperties()
655+
#if __IOS__
656+
internal
657+
#else
658+
private
659+
#endif
660+
void UpdateDimensionProperties()
656661
{
657662
if (this.Log().IsEnabled(LogLevel.Debug)
658663
&& (ActualHeight != ViewportHeight || ActualWidth != ViewportWidth)
@@ -858,7 +863,7 @@ void IFrameworkTemplatePoolAware.OnTemplateRecycled()
858863
}
859864
}
860865

861-
#region Content and TemplatedParent forwarding to the ScrollContentPresenter
866+
#region Content and TemplatedParent forwarding to the ScrollContentPresenter
862867
protected override void OnContentChanged(object oldValue, object newValue)
863868
{
864869
base.OnContentChanged(oldValue, newValue);
@@ -943,9 +948,9 @@ private void ClearContentTemplatedParent(object oldContent)
943948
provider.Store.ClearValue(provider.Store.TemplatedParentProperty, DependencyPropertyValuePrecedences.Local);
944949
}
945950
}
946-
#endregion
951+
#endregion
947952

948-
#region Managed scroll bars support
953+
#region Managed scroll bars support
949954
private bool _isTemplateApplied;
950955
private ScrollBar? _verticalScrollbar;
951956
private ScrollBar? _horizontalScrollbar;
@@ -1100,7 +1105,7 @@ private void OnHorizontalScrollBarScrolled(object sender, ScrollEventArgs e)
11001105

11011106
ChangeViewScroll(e.NewValue, null, disableAnimation: immediate);
11021107
}
1103-
#endregion
1108+
#endregion
11041109

11051110
// Presenter to Control, i.e. OnPresenterScrolled
11061111
internal void OnScrollInternal(double horizontalOffset, double verticalOffset, bool isIntermediate)
@@ -1214,7 +1219,7 @@ public bool ChangeView(double? horizontalOffset, double? verticalOffset, float?
12141219
partial void ChangeViewScroll(double? horizontalOffset, double? verticalOffset, bool disableAnimation);
12151220
partial void ChangeViewZoom(float zoomFactor, bool disableAnimation);
12161221

1217-
#region Scroll indicators visual states (Managed scroll bars only)
1222+
#region Scroll indicators visual states (Managed scroll bars only)
12181223
private DispatcherQueueTimer? _indicatorResetTimer;
12191224
private string? _indicatorState;
12201225

@@ -1293,6 +1298,6 @@ private void HideScrollBarSeparator(object sender, PointerRoutedEventArgs e) //
12931298
VisualStateManager.GoToState(this, VisualStates.ScrollBarsSeparator.Collapsed, true);
12941299
}
12951300
}
1296-
#endregion
1301+
#endregion
12971302
}
12981303
}

0 commit comments

Comments
 (0)