ScrollView: Always fire onScroll event for the resting scroll position

Summary:
When throttling scroll events with `scrollEventThrottle`, `onScroll`
is not guaranteed to be fired for the final scroll position
of the `ScrollView`. This can cause a component to render UI that
is consistent with the resting scroll position of the `ScrollView`.

This commit guarantees that an `onScroll` event will be fired for
the resting scroll position of the `ScrollView`.

**Test plan (required)**

Verified commit fixes a reduced repro. Also tested fix in a larger app.

Adam Comella
Microsoft Corp.
Closes https://github.com/facebook/react-native/pull/7366

Differential Revision: D3269303

Pulled By: javache

fb-gh-sync-id: f68ecb7e9c18d1ac255c6f872fb7eb4aadd07799
fbshipit-source-id: f68ecb7e9c18d1ac255c6f872fb7eb4aadd07799
This commit is contained in:
Adam Comella 2016-05-06 03:18:20 -07:00 committed by Facebook Github Bot 2
parent 4d2c72b977
commit deef8aade2

View File

@ -399,7 +399,7 @@ RCT_NOT_IMPLEMENTED(- (instancetype)init)
_lastClippedToRect = CGRectNull;
_scrollEventThrottle = 0.0;
_lastScrollDispatchTime = CACurrentMediaTime();
_lastScrollDispatchTime = 0;
_cachedChildFrames = [NSMutableArray new];
[self addSubview:_scrollView];
@ -544,6 +544,8 @@ RCT_NOT_IMPLEMENTED(- (instancetype)initWithCoder:(NSCoder *)aDecoder)
- (void)scrollToOffset:(CGPoint)offset animated:(BOOL)animated
{
if (!CGPointEqualToPoint(_scrollView.contentOffset, offset)) {
// Ensure at least one scroll event will fire
_allowNextScrollNoMatterWhat = YES;
[_scrollView setContentOffset:offset animated:animated];
}
}
@ -579,9 +581,7 @@ if ([_nativeScrollDelegate respondsToSelector:_cmd]) { \
RCT_FORWARD_SCROLL_EVENT(delegateMethod:scrollView); \
}
RCT_SCROLL_EVENT_HANDLER(scrollViewDidEndScrollingAnimation, onMomentumScrollEnd) //TODO: shouldn't this be onScrollAnimationEnd?
RCT_SCROLL_EVENT_HANDLER(scrollViewWillBeginDecelerating, onMomentumScrollBegin)
RCT_SCROLL_EVENT_HANDLER(scrollViewDidEndDecelerating, onMomentumScrollEnd)
RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, onScroll)
- (void)scrollViewDidScroll:(UIScrollView *)scrollView
@ -725,6 +725,28 @@ RCT_SCROLL_EVENT_HANDLER(scrollViewDidZoom, onScroll)
RCT_FORWARD_SCROLL_EVENT(scrollViewDidEndZooming:scrollView withView:view atScale:scale);
}
- (void)scrollViewDidEndDecelerating:(UIScrollView *)scrollView
{
// Fire a final scroll event
_allowNextScrollNoMatterWhat = YES;
[self scrollViewDidScroll:scrollView];
// Fire the end deceleration event
RCT_SEND_SCROLL_EVENT(onMomentumScrollEnd, nil);
RCT_FORWARD_SCROLL_EVENT(scrollViewDidEndDecelerating:scrollView);
}
- (void)scrollViewDidEndScrollingAnimation:(UIScrollView *)scrollView
{
// Fire a final scroll event
_allowNextScrollNoMatterWhat = YES;
[self scrollViewDidScroll:scrollView];
// Fire the end deceleration event
RCT_SEND_SCROLL_EVENT(onMomentumScrollEnd, nil); //TODO: shouldn't this be onScrollAnimationEnd?
RCT_FORWARD_SCROLL_EVENT(scrollViewDidEndScrollingAnimation:scrollView);
}
- (BOOL)scrollViewShouldScrollToTop:(UIScrollView *)scrollView
{
if ([_nativeScrollDelegate respondsToSelector:_cmd]) {