mirror of
https://github.com/facebook/react-native.git
synced 2024-11-21 22:10:14 +00:00
Fix onMomentumScrollBegin not dispatching from animations (#47468)
Summary: Pull Request resolved: https://github.com/facebook/react-native/pull/47468 Across our scroll view implementations on iOS, we fire `onMomentumScrollEnd` whenever the scroll view finishes decelerating, whether it comes from a user's touch or call to `setContentOffset` with animations. But we omit dispatching the `onMomentumScrollBegin` event in the latter cases. This change updates both old and new architecture to dispatch `onMomentumScrollBegin` when a view-command-driven scroll occurs with animation, like `scrollTo` or `scrollToEnd`. Changelog: [iOS][Fixed] - Fixed `onMomentumScrollBegin` event not firing on command-driven scroll events Reviewed By: javache Differential Revision: D65556000 fbshipit-source-id: bc4b778c63d8a032e1d8e00b9d4d5f83a5d651d6
This commit is contained in:
parent
6295b81e79
commit
5b609cca09
@ -903,6 +903,8 @@ static inline UIViewAnimationOptions animationOptionsWithCurve(UIViewAnimationCu
|
||||
// When not animated, the expected workflow in ``scrollViewDidEndScrollingAnimation`` after scrolling is not going
|
||||
// to get triggered. We will need to manually execute here.
|
||||
[self _handleFinishedScrolling:_scrollView];
|
||||
} else if (_eventEmitter) {
|
||||
static_cast<const ScrollViewEventEmitter &>(*_eventEmitter).onMomentumScrollBegin([self _scrollViewMetrics]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -600,6 +600,9 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(
|
||||
offset = CGPointMake(x, y);
|
||||
}
|
||||
[_scrollView setContentOffset:offset animated:animated];
|
||||
if (animated) {
|
||||
[self sendScrollEventWithName:@"onMomentumScrollBegin" scrollView:_scrollView userData:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -622,6 +625,9 @@ static inline void RCTApplyTransformationAccordingLayoutDirection(
|
||||
// Ensure at least one scroll event will fire
|
||||
_allowNextScrollNoMatterWhat = YES;
|
||||
[_scrollView setContentOffset:offset animated:animated];
|
||||
if (animated) {
|
||||
[self sendScrollEventWithName:@"onMomentumScrollBegin" scrollView:_scrollView userData:nil];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,7 +15,7 @@ import RNTesterText from '../../components/RNTesterText';
|
||||
import ScrollViewPressableStickyHeaderExample from './ScrollViewPressableStickyHeaderExample';
|
||||
import nullthrows from 'nullthrows';
|
||||
import * as React from 'react';
|
||||
import {useCallback, useState} from 'react';
|
||||
import {useCallback, useRef, useState} from 'react';
|
||||
import {
|
||||
Platform,
|
||||
RefreshControl,
|
||||
@ -855,11 +855,21 @@ const OnScrollOptions = () => {
|
||||
};
|
||||
|
||||
const OnMomentumScroll = () => {
|
||||
const ref = useRef<?React.ElementRef<typeof ScrollView>>(null);
|
||||
const [scroll, setScroll] = useState('none');
|
||||
return (
|
||||
<View>
|
||||
<RNTesterText>Scroll State: {scroll}</RNTesterText>
|
||||
<Button
|
||||
label="scrollTo top (animated)"
|
||||
onPress={() => ref.current?.scrollTo({x: 0, y: 0, animated: true})}
|
||||
/>
|
||||
<Button
|
||||
label="scrollTo top (not animated)"
|
||||
onPress={() => ref.current?.scrollTo({x: 0, y: 0, animated: false})}
|
||||
/>
|
||||
<ScrollView
|
||||
ref={ref}
|
||||
style={[styles.scrollView, {height: 200}]}
|
||||
onMomentumScrollBegin={() => setScroll('onMomentumScrollBegin')}
|
||||
onMomentumScrollEnd={() => setScroll('onMomentumScrollEnd')}
|
||||
|
Loading…
Reference in New Issue
Block a user