@@ -111,8 +111,6 @@ protected override UIView CreatePlatformView()
111111
112112 layoutSetup . ConfigureCollectionView ( collectionView ) ;
113113
114- _dragGestureRecognizer = CreateDragGestureRecognizer ( virtualScroll , collectionView ) ;
115-
116114 _reuseIdManager = reuseIdManager ;
117115 _collectionView = collectionView ;
118116
@@ -170,49 +168,60 @@ private void RefreshControlEventHandler(object? sender, EventArgs e)
170168 }
171169 }
172170
173- private static UILongPressGestureRecognizer CreateDragGestureRecognizer ( IVirtualScroll virtualView , VirtualScrollCollectionView collectionView )
174- => new ( gesture =>
171+ private static UILongPressGestureRecognizer CreateDragGestureRecognizer ( )
172+ => new ( HandleLongPress ) ;
173+
174+ // ReSharper disable once MemberCanBeMadeStatic.Local
175+ private static void HandleLongPress ( UILongPressGestureRecognizer gesture )
176+ {
177+ if ( gesture . View is not VirtualScrollCollectionView cv )
178+ {
179+ return ;
180+ }
181+
182+ switch ( gesture . State )
183+ {
184+ case UIGestureRecognizerState . Began :
175185 {
176- switch ( gesture . State )
186+ var location = gesture . LocationInView ( cv ) ;
187+ var indexPath = cv . IndexPathForItemAtPoint ( location ) ;
188+
189+ if ( indexPath is not null && cv . CellForItem ( indexPath ) is { } cell )
177190 {
178- case UIGestureRecognizerState . Began :
179- {
180- var location = gesture . LocationInView ( collectionView ) ;
181- var indexPath = collectionView . IndexPathForItemAtPoint ( location ) ;
182- if ( indexPath is not null && collectionView . CellForItem ( indexPath ) is { } cell )
183- {
184- ( ( VirtualScrollDelegate ) collectionView . Delegate ) . ItemDragInitiating ( indexPath ) ;
185- indexPath = collectionView . IndexPathForCell ( cell ) ;
186- if ( indexPath is not null )
187- {
188- collectionView . BeginInteractiveMovementForItem ( indexPath ) ;
189- }
190- }
191-
192- break ;
193- }
194- case UIGestureRecognizerState . Changed :
195- {
196- var location = gesture . LocationInView ( collectionView ) ;
197- collectionView . UpdateInteractiveMovement ( location ) ;
191+ ( ( VirtualScrollDelegate ) cv . Delegate ) . ItemDragInitiating ( indexPath ) ;
192+ indexPath = cv . IndexPathForCell ( cell ) ;
198193
199- break ;
200- }
201- case UIGestureRecognizerState . Ended :
202- {
203- collectionView . EndInteractiveMovement ( ) ;
204- ( ( VirtualScrollDelegate ) collectionView . Delegate ) . ItemDragEnded ( ) ;
205- break ;
206- }
207- default :
194+ if ( indexPath is not null )
208195 {
209- collectionView . CancelInteractiveMovement ( ) ;
210- ( ( VirtualScrollDelegate ) collectionView . Delegate ) . ItemDragEnded ( ) ;
211- break ;
196+ cv . BeginInteractiveMovementForItem ( indexPath ) ;
212197 }
213198 }
199+
200+ break ;
214201 }
215- ) ;
202+ case UIGestureRecognizerState . Changed :
203+ {
204+ var location = gesture . LocationInView ( cv ) ;
205+ cv . UpdateInteractiveMovement ( location ) ;
206+
207+ break ;
208+ }
209+ case UIGestureRecognizerState . Ended :
210+ {
211+ cv . EndInteractiveMovement ( ) ;
212+ ( ( VirtualScrollDelegate ) cv . Delegate ) . ItemDragEnded ( ) ;
213+
214+ break ;
215+ }
216+ default :
217+ {
218+ cv . CancelInteractiveMovement ( ) ;
219+ ( ( VirtualScrollDelegate ) cv . Delegate ) . ItemDragEnded ( ) ;
220+
221+ break ;
222+ }
223+ }
224+ }
216225
217226 private void OnBoundsChanged ( object ? sender , EventArgs e )
218227 {
@@ -316,9 +325,14 @@ protected override void DisconnectHandler(UIView platformView)
316325 _delegate ? . Dispose ( ) ;
317326 _delegate = null ;
318327
328+ if ( _dragGestureRecognizer is not null )
329+ {
330+ _collectionView ? . RemoveGestureRecognizer ( _dragGestureRecognizer ) ;
331+ _dragGestureRecognizer . Dispose ( ) ;
332+ _dragGestureRecognizer = null ;
333+ }
319334 _collectionView ? . Dispose ( ) ;
320335 _collectionView = null ;
321- _dragGestureRecognizer ? . Dispose ( ) ;
322336 _containerView ? . Dispose ( ) ;
323337 _containerView = null ;
324338 _lastBounds = CGSize . Empty ;
@@ -336,16 +350,17 @@ public static void MapDragHandler(VirtualScrollHandler handler, IVirtualScroll v
336350 {
337351 var collectionView = handler . PlatformCollectionView ;
338352 var isDragEnabled = virtualScroll . DragHandler is not null ;
339- var dragGestureRecognizer = handler . _dragGestureRecognizer ?? throw new InvalidOperationException ( "Drag gesture recognizer is not initialized." ) ;
340-
353+
341354 if ( isDragEnabled )
342355 {
343-
344- collectionView . AddGestureRecognizer ( dragGestureRecognizer ) ;
356+ handler . _dragGestureRecognizer ??= CreateDragGestureRecognizer ( ) ;
357+ collectionView . AddGestureRecognizer ( handler . _dragGestureRecognizer ) ;
345358 }
346- else
359+ else if ( handler . _dragGestureRecognizer is not null )
347360 {
348- collectionView . RemoveGestureRecognizer ( dragGestureRecognizer ) ;
361+ collectionView . RemoveGestureRecognizer ( handler . _dragGestureRecognizer ) ;
362+ handler . _dragGestureRecognizer . Dispose ( ) ;
363+ handler . _dragGestureRecognizer = null ;
349364 }
350365 }
351366
@@ -407,10 +422,37 @@ public static void MapLayout(VirtualScrollHandler handler, IVirtualScroll virtua
407422 handler . _delegate ? . UpdateFadingEdge ( handler . _collectionView ) ;
408423 }
409424 }
425+
426+ private struct VirtualScrollLayoutInfo : IVirtualScrollLayoutInfo
427+ {
428+ public VirtualScrollLayoutInfo ( IVirtualScrollLayoutInfo virtualScroll )
429+ {
430+ HasGlobalFooter = virtualScroll . HasGlobalFooter ;
431+ HasGlobalHeader = virtualScroll . HasGlobalHeader ;
432+ HasSectionFooter = virtualScroll . HasSectionFooter ;
433+ HasSectionHeader = virtualScroll . HasSectionHeader ;
434+ }
435+
436+ public bool Equals ( IVirtualScrollLayoutInfo ? other ) =>
437+ other != null &&
438+ HasGlobalFooter == other . HasGlobalFooter &&
439+ HasGlobalHeader == other . HasGlobalHeader &&
440+ HasSectionFooter == other . HasSectionFooter &&
441+ HasSectionHeader == other . HasSectionHeader ;
442+
443+
444+ public bool HasGlobalHeader { get ; }
445+ public bool HasGlobalFooter { get ; }
446+ public bool HasSectionHeader { get ; }
447+ public bool HasSectionFooter { get ; }
448+ }
410449
411450 private static VirtualScrollCollectionViewLayoutSetup CreatePlatformLayout ( VirtualScrollHandler handler , IVirtualScroll virtualScroll )
412451 {
413- var layoutInfo = virtualScroll as IVirtualScrollLayoutInfo ?? throw new InvalidOperationException ( "The provided IVirtualScroll does not implement IVirtualScrollLayoutInfo interface." ) ;
452+ var layoutInfo = new VirtualScrollLayoutInfo (
453+ virtualScroll as IVirtualScrollLayoutInfo ??
454+ throw new InvalidOperationException ( "The provided IVirtualScroll does not implement IVirtualScrollLayoutInfo interface." )
455+ ) ;
414456
415457 var layoutSetup = virtualScroll . ItemsLayout switch
416458 {
0 commit comments