Skip to content

Commit 1d36700

Browse files
sophiebitsfacebook-github-bot
authored andcommitted
Improve feel of scroll snapping behavior on iOS
Reviewed By: sahrens, shergin Differential Revision: D4768384 fbshipit-source-id: 6319d058292be6ba38c059d8d1a1bf70bac603e2
1 parent c233191 commit 1d36700

File tree

1 file changed

+11
-20
lines changed

1 file changed

+11
-20
lines changed

React/Views/RCTScrollView.m

+11-20
Original file line numberDiff line numberDiff line change
@@ -326,10 +326,6 @@ @implementation RCTScrollView
326326
uint16_t _coalescingKey;
327327
NSString *_lastEmittedEventName;
328328
NSHashTable *_scrollListeners;
329-
// The last non-zero value of translationAlongAxis from scrollViewWillEndDragging.
330-
// Tells if user was scrolling forward or backward and is used to determine a correct
331-
// snap index when the user stops scrolling with a tap on the scroll view.
332-
CGFloat _lastNonZeroTranslationAlongAxis;
333329
}
334330

335331
- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
@@ -667,32 +663,27 @@ - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoi
667663
BOOL isHorizontal = [self isHorizontal:scrollView];
668664

669665
// What is the current offset?
666+
CGFloat velocityAlongAxis = isHorizontal ? velocity.x : velocity.y;
670667
CGFloat targetContentOffsetAlongAxis = isHorizontal ? targetContentOffset->x : targetContentOffset->y;
671668

672-
// Which direction is the scroll travelling?
673-
CGPoint translation = [scrollView.panGestureRecognizer translationInView:scrollView];
674-
CGFloat translationAlongAxis = isHorizontal ? translation.x : translation.y;
675-
676669
// Offset based on desired alignment
677670
CGFloat frameLength = isHorizontal ? self.frame.size.width : self.frame.size.height;
678671
CGFloat alignmentOffset = 0.0f;
679-
if ([self.snapToAlignment isEqualToString: @"center"]) {
672+
if ([self.snapToAlignment isEqualToString: @"center"]) {
680673
alignmentOffset = (frameLength * 0.5f) + (snapToIntervalF * 0.5f);
681-
} else if ([self.snapToAlignment isEqualToString: @"end"]) {
674+
} else if ([self.snapToAlignment isEqualToString: @"end"]) {
682675
alignmentOffset = frameLength;
683676
}
684677

685678
// Pick snap point based on direction and proximity
686-
NSInteger snapIndex = floor((targetContentOffsetAlongAxis + alignmentOffset) / snapToIntervalF);
687-
BOOL isScrollingForward = translationAlongAxis < 0;
688-
BOOL wasScrollingForward = translationAlongAxis == 0 && _lastNonZeroTranslationAlongAxis < 0;
689-
if (isScrollingForward || wasScrollingForward) {
690-
snapIndex = snapIndex + 1;
691-
}
692-
if (translationAlongAxis != 0) {
693-
_lastNonZeroTranslationAlongAxis = translationAlongAxis;
694-
}
695-
CGFloat newTargetContentOffset = ( snapIndex * snapToIntervalF ) - alignmentOffset;
679+
CGFloat fractionalIndex = (targetContentOffsetAlongAxis + alignmentOffset) / snapToIntervalF;
680+
NSInteger snapIndex =
681+
velocityAlongAxis > 0.0 ?
682+
ceil(fractionalIndex) :
683+
velocityAlongAxis < 0.0 ?
684+
floor(fractionalIndex) :
685+
round(fractionalIndex);
686+
CGFloat newTargetContentOffset = (snapIndex * snapToIntervalF) - alignmentOffset;
696687

697688
// Set new targetContentOffset
698689
if (isHorizontal) {

0 commit comments

Comments
 (0)