Skip to content

Commit

Permalink
Fix ScrollView's snap index when scrolling forward and user taps the …
Browse files Browse the repository at this point in the history
…screen again while still scrolling

Summary:
Currently when snapping is used with ScrollView it calculates wrong snap index if user taps the screen second time while ScrollView is still scrolling. This happens because the code only adds 1 to the snap index when translationAlongAxis is smaller than zero. When user taps screen second time the translationAlongAxis is 0 and snap index ends up being one less than it should. This causes the ScrollView to scroll one step backwards.

Bug can be reproduced with the new examples I added to UIExplorer's ScrollView in [scrollview-snap-bug-example branch](https://github.com/anttimo/react-native/tree/scrollview-snap-bug-example).

Fix can be verified by running the same examples with the ScrollView fix in [scrollview-snap-bug-example-with-fix branch](https://github.com/anttimo/react-native/tree/scrollview-snap-bug-example-with-fix).

![scrollview-bug](https://cloud.githubusercontent.com/assets/150881/14427555/10d59d1e-fffe-11
Closes #6906

Differential Revision: D3927123

Pulled By: majak

fbshipit-source-id: 38828cc60a02a754bdc3ec72fb98d8777917f15e
  • Loading branch information
anttimo authored and Facebook Github Bot 7 committed Sep 26, 2016
1 parent 0ce2bbd commit 72e203b
Showing 1 changed file with 12 additions and 1 deletion.
13 changes: 12 additions & 1 deletion React/Views/RCTScrollView.m
Original file line number Diff line number Diff line change
Expand Up @@ -381,6 +381,10 @@ @implementation RCTScrollView
uint16_t _coalescingKey;
NSString *_lastEmittedEventName;
NSHashTable *_scrollListeners;
// The last non-zero value of translationAlongAxis from scrollViewWillEndDragging.
// Tells if user was scrolling forward or backward and is used to determine a correct
// snap index when the user stops scrolling with a tap on the scroll view.
CGFloat _lastNonZeroTranslationAlongAxis;
}

- (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
Expand Down Expand Up @@ -699,7 +703,14 @@ - (void)scrollViewWillEndDragging:(UIScrollView *)scrollView withVelocity:(CGPoi

// Pick snap point based on direction and proximity
NSInteger snapIndex = floor((targetContentOffsetAlongAxis + alignmentOffset) / snapToIntervalF);
snapIndex = (translationAlongAxis < 0) ? snapIndex + 1 : snapIndex;
BOOL isScrollingForward = translationAlongAxis < 0;
BOOL wasScrollingForward = translationAlongAxis == 0 && _lastNonZeroTranslationAlongAxis < 0;
if (isScrollingForward || wasScrollingForward) {
snapIndex = snapIndex + 1;
}
if (translationAlongAxis != 0) {
_lastNonZeroTranslationAlongAxis = translationAlongAxis;
}
CGFloat newTargetContentOffset = ( snapIndex * snapToIntervalF ) - alignmentOffset;

// Set new targetContentOffset
Expand Down

0 comments on commit 72e203b

Please sign in to comment.