Skip to content

Commit

Permalink
ScrollView: Always fire onScroll event for the resting scroll position
Browse files Browse the repository at this point in the history
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 #7366

Differential Revision: D3269303

Pulled By: javache

fb-gh-sync-id: f68ecb7e9c18d1ac255c6f872fb7eb4aadd07799
fbshipit-source-id: f68ecb7e9c18d1ac255c6f872fb7eb4aadd07799
  • Loading branch information
Adam Comella authored and Facebook Github Bot 2 committed May 6, 2016
1 parent 4d2c72b commit deef8aa
Showing 1 changed file with 25 additions and 3 deletions.
28 changes: 25 additions & 3 deletions React/Views/RCTScrollView.m
Original file line number Diff line number Diff line change
Expand Up @@ -399,7 +399,7 @@ - (instancetype)initWithEventDispatcher:(RCTEventDispatcher *)eventDispatcher
_lastClippedToRect = CGRectNull;

_scrollEventThrottle = 0.0;
_lastScrollDispatchTime = CACurrentMediaTime();
_lastScrollDispatchTime = 0;
_cachedChildFrames = [NSMutableArray new];

[self addSubview:_scrollView];
Expand Down Expand Up @@ -544,6 +544,8 @@ - (void)scrollToOffset:(CGPoint)offset
- (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];
}
}
Expand Down Expand Up @@ -579,9 +581,7 @@ - (void)delegateMethod:(UIScrollView *)scrollView \
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
Expand Down Expand Up @@ -725,6 +725,28 @@ - (void)scrollViewDidEndZooming:(UIScrollView *)scrollView withView:(UIView *)vi
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]) {
Expand Down

0 comments on commit deef8aa

Please sign in to comment.