On Android when ViewPager is scrolling with swipe gesture all content(including all Touchables) are disabled. On iOS it's not - all touchables are interactable while swiping so when viewpager content has button or other clickable components they are clicked.
I tried to fix it with setUserInteractioEnabled and with UIGestureRecognizer, but haven't come up with any idea how to fix. Problem is to cancel all currently tapped touchables events when scroll begins.
React native info output:
info
React Native Environment Info:
System:
OS: macOS 10.15
CPU: (12) x64 Intel(R) Core(TM) i9-8950HK CPU @ 2.90GHz
Memory: 1.36 GB / 16.00 GB
Shell: 5.7.1 - /bin/zsh
Binaries:
Node: 10.16.3 - /usr/local/bin/node
Yarn: 1.19.0 - /usr/local/bin/yarn
npm: 6.11.3 - /usr/local/bin/npm
Watchman: 4.9.0 - /usr/local/bin/watchman
SDKs:
iOS SDK:
Platforms: iOS 13.0, DriverKit 19.0, macOS 10.15, tvOS 13.0, watchOS 6.0
Android SDK:
API Levels: 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 7, 8, 9
Build Tools: 27.0.3, 28.0.2, 28.0.3, 29.0.2
System Images: android-16 | Intel x86 Atom, android-18 | Google APIs Intel x86 Atom, android-19 | Google APIs Intel x86 Atom, android-21 | Intel x86 Atom, android-22 | Google APIs Intel x86 Atom, android-23 | Google APIs Intel x86 Atom, android-24 | Google Play Intel x86 Atom, android-27 | Google APIs Intel x86 Atom, android-28 | Android TV Intel x86 Atom, android-28 | Google Play Intel x86 Atom
IDEs:
Android Studio: 3.5 AI-191.8026.42.35.5900203
Xcode: 11.0/11A420a - /usr/bin/xcodebuild
npmPackages:
react: 16.8.6 => 16.8.6
react-native: 0.59.10 => 0.59.10
npmGlobalPackages:
react-native-cli: 2.0.1
react-native-git-upgrade: 0.2.7
react-native-rename: 2.4.1
Library version: 2.0.1
Use ViewPager on iOS with any touchable components inside
Hey,
you can use onPageScrollStateChanged method, to block button interaction.
switch(pageScrollState){
case "idle": enableButton();
default: disableButton();
}
Hey,
you can useonPageScrollStateChangedmethod, to block button interaction.switch(pageScrollState){ case "idle": enableButton(); default: disableButton(); }
i dont think this is a good solution...
Any fix ?
I add onMoveShouldSetResponderCapture method to ViewPager to prevent the touch event pass to the child view when viewpager is scrolling:
onPageScroll(evt) {
this.setState({pageScrolling: true});
}
onPageScrollStateChanged(evt) {
if ('idle' == evt.nativeEvent.pageScrollState) {
this.setState({pageScrolling: false});
} else {
this.setState({pageScrolling: true});
}
}
moveShouldSetResponderCapture(evt) {
return this.state.pageScrolling;
}
render() {
return (
<ViewPager style={styles.viewPager}
initialPage={0}
scrollEnabled={this.state.scrollEnabled}
onPageSelected={this.onPageSelected}
orientation="horizontal"
transitionStyle="scroll"
showPageIndicator={false}
animationsAreEnabled={animationsAreEnabled}
onPageScroll={(evt) => this.onPageScroll(evt)}
onPageScrollStateChanged={(evt) => this.onPageScrollStateChanged(evt)}
onMoveShouldSetResponderCapture={(evt) => this.moveShouldSetResponderCapture(evt)}
ref={this.viewPager}
>
{pages.map(p => this.renderPage(p))}
</ViewPager>
)
}
I have created PR for it. Thank you @ljsalm089 for providing above example. It helped me a lot.
the branch from @troZee fixed the problem
Most helpful comment
I add
onMoveShouldSetResponderCapturemethod to ViewPager to prevent the touch event pass to the child view when viewpager is scrolling: