@@ -22,6 +22,7 @@ public partial class VirtualScrollHandler
2222 private VirtualScrollCollectionView ? _collectionView ;
2323 private VirtualScrollContainerView ? _containerView ;
2424 private UILongPressGestureRecognizer ? _dragGestureRecognizer ;
25+ private CGSize _lastBounds ;
2526
2627 /// <summary>
2728 /// Gets the <see cref="UICollectionView"/> platform view.
@@ -149,8 +150,8 @@ protected override UIView CreatePlatformView()
149150 _containerView = new VirtualScrollContainerView ( ) ;
150151
151152 // Subscribe to events for fading edge updates
152- _containerView . BoundsChanged += OnFadingEdgeBoundsChanged ;
153- collectionView . ContentSizeChanged += OnFadingEdgeBoundsChanged ;
153+ _containerView . BoundsChanged += OnBoundsChanged ;
154+ collectionView . ContentSizeChanged += OnContentSizeChanged ;
154155
155156 var containerView = _containerView ;
156157 collectionView . TranslatesAutoresizingMaskIntoConstraints = false ;
@@ -210,7 +211,56 @@ private static UILongPressGestureRecognizer CreateDragGestureRecognizer(IVirtual
210211 }
211212 ) ;
212213
213- private void OnFadingEdgeBoundsChanged ( object ? s , EventArgs e )
214+ private void OnBoundsChanged ( object ? sender , EventArgs e )
215+ {
216+ if ( _collectionView is not null )
217+ {
218+ _delegate ? . UpdateFadingEdge ( _collectionView ) ;
219+
220+ // Maintain carousel snap to the first page
221+ if ( _collectionView . PagingEnabled && VirtualView ? . ItemsLayout is { Orientation : var orientation } )
222+ {
223+ var bounds = _collectionView . Bounds ;
224+ var contentSize = _collectionView . ContentSize ;
225+ var scrollX = _collectionView . ContentOffset . X ;
226+ var scrollY = _collectionView . ContentOffset . Y ;
227+ nfloat ? newX = null , newY = null ;
228+
229+ if ( orientation == ItemsLayoutOrientation . Horizontal )
230+ {
231+ var pageWidth = bounds . Width ;
232+ if ( pageWidth > 0 && _lastBounds . Width > 0 && contentSize . Width > 0 )
233+ {
234+ var page = Math . Round ( scrollX / _lastBounds . Width ) ;
235+ var snapX = ( nfloat ) ( page * pageWidth ) ;
236+ var maxX = contentSize . Width - pageWidth ;
237+ newX = ( nfloat ) Math . Max ( 0 , Math . Min ( maxX , snapX ) ) ;
238+ newY = scrollY ;
239+ }
240+ }
241+ else
242+ {
243+ var pageHeight = bounds . Height ;
244+ if ( pageHeight > 0 && _lastBounds . Height > 0 && contentSize . Height > 0 )
245+ {
246+ var page = Math . Round ( scrollY / _lastBounds . Height ) ;
247+ var snapY = ( nfloat ) ( page * pageHeight ) ;
248+ var maxY = contentSize . Height - pageHeight ;
249+ newX = scrollX ;
250+ newY = ( nfloat ) Math . Max ( 0 , Math . Min ( maxY , snapY ) ) ;
251+ }
252+ }
253+
254+ if ( newX is { } x && newY is { } y )
255+ {
256+ _collectionView . SetContentOffset ( new CGPoint ( x , y ) , false ) ;
257+ }
258+ }
259+
260+ _lastBounds = _collectionView . Bounds . Size ;
261+ }
262+ }
263+ private void OnContentSizeChanged ( object ? s , EventArgs e )
214264 {
215265 if ( _collectionView is not null )
216266 {
@@ -243,12 +293,12 @@ protected override void DisconnectHandler(UIView platformView)
243293 // Unsubscribe from events
244294 if ( _containerView is not null )
245295 {
246- _containerView . BoundsChanged -= OnFadingEdgeBoundsChanged ;
296+ _containerView . BoundsChanged -= OnBoundsChanged ;
247297 }
248298
249299 if ( _collectionView is not null )
250300 {
251- _collectionView . ContentSizeChanged -= OnFadingEdgeBoundsChanged ;
301+ _collectionView . ContentSizeChanged -= OnContentSizeChanged ;
252302 _collectionView . DataSource = null ! ;
253303 _collectionView . Delegate = null ! ;
254304 _collectionView . RefreshControl = null ;
@@ -262,6 +312,7 @@ protected override void DisconnectHandler(UIView platformView)
262312 _dragGestureRecognizer ? . Dispose ( ) ;
263313 _containerView ? . Dispose ( ) ;
264314 _containerView = null ;
315+ _lastBounds = CGSize . Empty ;
265316 _reuseIdManager = null ;
266317
267318 base . DisconnectHandler ( platformView ) ;
0 commit comments