@@ -459,18 +459,20 @@ extension AnyListLayout
459459 func onDidEndDraggingTargetContentOffset(
460460 for targetContentOffset : CGPoint ,
461461 velocity : CGPoint ,
462- visibleContentSize : CGSize
462+ visibleContentFrame : CGRect
463463 ) -> CGPoint ?
464464 {
465465 guard self . pagingBehavior != . none else { return nil }
466-
466+
467467 guard let item = self . itemToScrollToOnDidEndDragging (
468468 after: targetContentOffset,
469- velocity: velocity
469+ velocity: velocity,
470+ visibleContentFrame: visibleContentFrame
470471 ) else {
471472 return nil
472473 }
473474
475+ let visibleContentSize = visibleContentFrame. size
474476 let padding = self . bounds? . padding ?? . zero
475477
476478 switch self . pagingBehavior {
@@ -493,39 +495,84 @@ extension AnyListLayout
493495
494496 func itemToScrollToOnDidEndDragging(
495497 after contentOffset : CGPoint ,
496- velocity : CGPoint
498+ velocity : CGPoint ,
499+ visibleContentFrame: CGRect
497500 ) -> ListLayoutContent . ContentItem ?
498501 {
499- let rect : CGRect = self . rectForFindingItemToScrollToOnDidEndDragging (
500- after: contentOffset,
501- velocity: velocity
502- )
502+ let rect : CGRect
503+ if scrollViewProperties. pageScrollingBehavior == . peek {
504+ /// When peeking, the visible items are the only items considered for the page offest.
505+ rect = visibleContentFrame
506+ } else {
507+ rect = self . rectForFindingItemToScrollToOnDidEndDragging (
508+ after: contentOffset,
509+ velocity: velocity
510+ )
511+ }
503512
504513 let scrollDirection = ScrollVelocityDirection ( direction. y ( for: velocity) )
505514
506515 let items = self . content. content (
507516 in: rect,
508517 alwaysIncludeOverscroll: false ,
509518 includeUnpopulated: false
510- ) . sorted { lhs, rhs in
511- switch scrollDirection {
512- case . forward:
513- return direction. minY ( for: lhs. defaultFrame) < direction. minY ( for: rhs. defaultFrame)
514- case . backward:
515- return direction. maxY ( for: lhs. defaultFrame) > direction. maxY ( for: rhs. defaultFrame)
516- }
517- }
518-
519- return items. first { item in
520- let edge = direction. minY ( for: item. defaultFrame)
521- let offset = direction. y ( for: contentOffset)
519+ )
520+
521+ if scrollViewProperties. pageScrollingBehavior == . peek {
522+ let mainAxisVelocity = direction. switch (
523+ vertical: { velocity. y } ,
524+ horizontal: { velocity. x }
525+ )
522526
523- switch scrollDirection {
524- case . forward:
525- return edge >= offset
526- case . backward:
527- return edge <= offset
527+ if mainAxisVelocity == 0 {
528+ /// When the items are being held still with custom paging, bias the most visible item.
529+ return items
530+ . sorted { lhs, rhs in
531+ lhs. percentageVisible ( inside: visibleContentFrame) > rhs. percentageVisible ( inside: visibleContentFrame)
532+ }
533+ . first
534+ } else {
535+ return items
536+ /// Sort items in ascending order, based on their position along the primary axis.
537+ . sorted { lhs, rhs in
538+ direction. minY ( for: lhs. defaultFrame) > direction. minY ( for: rhs. defaultFrame)
539+ }
540+ /// Using the visible sorted items, return the first that has a minimum edge outside the target offset.
541+ . first { item in
542+ let edge = direction. minY ( for: item. defaultFrame)
543+ let offset = direction. y ( for: contentOffset)
544+
545+ switch scrollDirection {
546+ case . forward:
547+ return edge >= offset
548+ case . backward:
549+ return edge <= offset
550+ }
551+ }
528552 }
553+ } else {
554+ return items
555+ /// Sort items based on their position on the primary axis, in ascending order.
556+ . sorted { lhs, rhs in
557+ switch scrollDirection {
558+ case . forward:
559+ return direction. minY ( for: lhs. defaultFrame) < direction. minY ( for: rhs. defaultFrame)
560+ case . backward:
561+ return direction. maxY ( for: lhs. defaultFrame) > direction. maxY ( for: rhs. defaultFrame)
562+ }
563+ }
564+ /// Using the sorted items, return the first has has a min edge outside the offset.
565+ . first { item in
566+ let edge = direction. minY ( for: item. defaultFrame)
567+ let offset = direction. y ( for: contentOffset)
568+
569+ switch scrollDirection {
570+ case . forward:
571+ return edge >= offset
572+ case . backward:
573+ return edge <= offset
574+ }
575+ }
529576 }
530577 }
531578
0 commit comments