react-native-modal
react-native-modal copied to clipboard
Inner scroll freezes when starts at 0 position on iOS
Environment
System: OS: macOS 11.5.2 CPU: (12) x64 Intel(R) Core(TM) i7-9750H CPU @ 2.60GHz Memory: 1.60 GB / 32.00 GB Shell: 3.2.57 - /bin/bash Binaries: Node: 12.18.2 - ~/.nvm/versions/node/v12.18.2/bin/node Yarn: 1.22.10 - /usr/local/bin/yarn npm: 6.14.5 - ~/.nvm/versions/node/v12.18.2/bin/npm Watchman: 2021.08.02.00 - /usr/local/bin/watchman Managers: CocoaPods: 1.10.2 - /usr/local/bin/pod SDKs: iOS SDK: Platforms: iOS 14.5, DriverKit 20.4, macOS 11.3, tvOS 14.5, watchOS 7.4 Android SDK: Android NDK: 20.0.5594570 IDEs: Android Studio: 4.1 AI-201.8743.12.41.7042882 Xcode: 12.5.1/12E507 - /usr/bin/xcodebuild Languages: Java: 15.0.1 - /usr/bin/javac Python: 2.7.16 - /usr/bin/python npmPackages: @react-native-community/cli: Not Found react: 16.13.1 => 16.13.1 react-native: 0.63.4 => 0.63.4 react-native-macos: Not Found npmGlobalPackages: react-native: Not Found
Platforms
Reproducing only on iOS. Android is OK.
Versions
- iOS: 11.0
- react-native-modal: bug on both 11.10.0 and 12.1.0
- react-native: 0.63.4
- react: 16.13.1
Description
When react-native-modal is used with ScrollView inside and long view nested in ScrollView it freezes up-scroll from default position (with zero offset) after first one or two renders. Scroll doesn't work until I release touch and scroll again. Here is the video of how it looks like. Doesn't matter I scroll fast or not. Reproduces approximately every second time. On the video touch is active when I rage-move mouse up and down, displaying scroll stopped working. When starting offset is not zero everything works fine, the problem is with 0 position. When I try to hack default offset to something like 0.001 scroll works, but modal closing with swipe-down stops working.
https://user-images.githubusercontent.com/13959241/130669172-970df2ca-40e6-4137-bb64-4f56a8b3df90.mp4
Reproducible Demo
I used an example from this repository. Here is my code:
class ModalShutter extends React.PureComponent<Props, State> {
scrollViewRef: ScrollView | null;
constructor(props: Props) {
super(props);
this.scrollViewRef = null;
this.state = {
scrollOffset: 0,
scrollOffsetMax: 0,
};
}
handleScrollTo = (p: Point): void => {
if (this.scrollViewRef) {
this.scrollViewRef.scrollTo(p);
}
};
render(): React.ReactNode {
const {
isVisible,
onClose,
scrollContent,
children,
stretched,
setScrollView,
backdropColor,
backdropOpacity,
} = this.props;
const {scrollOffset, scrollOffsetMax} = this.state;
return (
<Modal
isVisible={isVisible}
avoidKeyboard={true}
onSwipeComplete={onClose}
onBackButtonPress={onClose}
onBackdropPress={onClose}
swipeDirection={scrollContent ? undefined : 'down'}
scrollTo={this.handleScrollTo}
scrollOffset={scrollOffset}
scrollOffsetMax={scrollOffsetMax}
style={ModalShutterStyles.modal}
propagateSwipe={true}
useNativeDriver={false}
animationOutTiming={300}
backdropColor={backdropColor}
backdropOpacity={backdropOpacity}
>
<View
style={[
ModalShutterStyles.container,
stretched && ModalShutterStyles.stretchedContainer,
]}
>
<ScrollView
keyboardShouldPersistTaps={'handled'}
ref={ref => {
this.scrollViewRef = ref;
setScrollView?.(ref);
}}
onLayout={event => {
this.setState({scrollOffsetMax: event.nativeEvent.layout.height});
}}
onScroll={event => {
this.setState({scrollOffset: event.nativeEvent.contentOffset.y});
}}
scrollEventThrottle={16}
>
{children}
</ScrollView>
</View>
</Modal>
);
}
}
Here are ModalShutterStyles:
const ModalShutterStyles = StyleSheet.create({
modal: {
justifyContent: 'flex-end',
margin: 0,
},
container: {
backgroundColor: COLORS.backgroundLight,
borderTopLeftRadius: 16,
borderTopRightRadius: 16,
maxHeight: '85%',
},
stretchedContainer: {
height: '85%',
},
...
});
Any ideas?
I'm confused as to what you are doing with the scroll events. Im on my phone. I'll have to open this ticket in the browser to better understand what is going on here. Could you explain what you are attempting to achieve with the scroll events and how they tie into the modal events?
If I've understood your question correctly all the scroll events used in my code are taken from this scrollable modal example:
https://github.com/react-native-modal/react-native-modal/blob/master/example/src/modals/ScrollableModal.tsx
I have a same issue on both iOS and android. I think there are some conflicts between scrolling in scrollview and swiping a modal at 0 scroll position, but I couldn't find the solution. Any ideas?