Open a-sane opened 3 years ago
Face the same issue with ios + hermes on.
For more information
In the past, i'v use "@react-native-community/viewpager": "5.0.11"
and it work perfectly on android.
But currently when try ios build, this problem occured.
I'v also update to "react-native-pager-view": "5.4.0"
but this still persist.
The only solution that work for me now is listen for onPageScrollStateChanged
event, store the scroll state and only trigger onPress on other event if scrollState is idle
Depending on the type of touchable component you're using, you should be able to use the react-native-gesture-handler
version to get the desired behavior. These components are more tightly integrated with the native gesture system(s), and while I'm not entirely sure what changes were made to react-native-pager-view
from the old repo, it seems like it uses the react-native gesture responder system less.
P.S. While the react-native-gesture-handler docs say that TouchableWithoutFeedback and the like are drop-in replacements for the regular React-Native components, there are a few annoying differences regarding layout like this.
I have this problem on Android, and ignoring onPress
if scrollState !== 'idle'
helps (thank you, @kyoz). Unfortunately, onPageScrollStateChanged
does not fire 100% of the time. I have two nested PagerView components, and the the inner one's onPageScrollStateChanged
is unreliable when the outer one has recently scrolled. If I ignore onPress
until the outer PagerView has been idle for a period of time, the problem is less likely to occur.
I usereact-native-tab-view
v3 is depend on this, same issue!
I hope solve this problem.
I guess it's because of the async between the JavaScript thread
and Main Thread
.
If you use v2 (use react-native-reanimateed
builded), It won't happen.
Any update?
@grabbou Could we get an update on this please?
Found a solution!
Replace <TouchableHighlight
with <FixedTouchableHighlight
in your FlatList
// FixedTouchableHighlight.js
import React, { useRef } from 'react';
import { TouchableHighlight } from 'react-native';
export default function FixedTouchableHighlight({
onPress,
onPressIn,
...props
}) {
const _touchActivatePositionRef = useRef(null);
function _onPressIn(e) {
const { pageX, pageY } = e.nativeEvent;
_touchActivatePositionRef.current = {
pageX,
pageY,
};
onPressIn?.(e);
}
function _onPress(e) {
const { pageX, pageY } = e.nativeEvent;
const absX = Math.abs(_touchActivatePositionRef.current.pageX - pageX);
const absY = Math.abs(_touchActivatePositionRef.current.pageY - pageY);
const dragged = absX > 2 || absY > 2;
if (!dragged) {
onPress?.(e);
}
}
return (
<TouchableHighlight onPressIn={_onPressIn} onPress={_onPress} {...props}>
{props.children}
</TouchableHighlight>
);
}
@Gregoirevda Thank you for the workaround. Hopefully this is a temporary fix and a future update will prevent touchable from activating during screen transitions.
I have the same problem on React Navigation v6
Still an issue +1
Found a solution! Replace
<TouchableHighlight
with<FixedTouchableHighlight
in yourFlatList
// FixedTouchableHighlight.js import React, { useRef } from 'react'; import { TouchableHighlight } from 'react-native'; export default function FixedTouchableHighlight({ onPress, onPressIn, ...props }) { const _touchActivatePositionRef = useRef(null); function _onPressIn(e) { const { pageX, pageY } = e.nativeEvent; _touchActivatePositionRef.current = { pageX, pageY, }; onPressIn?.(e); } function _onPress(e) { const { pageX, pageY } = e.nativeEvent; const absX = Math.abs(_touchActivatePositionRef.current.pageX - pageX); const absY = Math.abs(_touchActivatePositionRef.current.pageY - pageY); const dragged = absX > 2 || absY > 2; if (!dragged) { onPress?.(e); } } return ( <TouchableHighlight onPressIn={_onPressIn} onPress={_onPress} {...props}> {props.children} </TouchableHighlight> ); }
Thank you @Gregoirevda for providing a temporary solution 🙏 it works! I even used it as
The issue is still present, currently on: "react-native-pager-view": "^6.2.0", "react-native-reanimated": "^2.10.0", "react-native": "0.70.7", "react-native-gesture-handler": "^2.6.0",
I just patched it react-native-tab-view/src/PanResponderAdapter.tsx
const panResponder = PanResponder.create({ onMoveShouldSetPanResponder: canMoveScreen,
// my change instead canMoveScreen
onMoveShouldSetPanResponderCapture: () => swipeEnabled,
onPanResponderGrant: startGesture,
onPanResponderMove: respondToGesture,
onPanResponderTerminate: finishGesture,
onPanResponderRelease: finishGesture,
onPanResponderTerminationRequest: () => true,
});
I hope it helps someone I applied the solution from https://github.com/facebook/react-native/issues/27355#issuecomment-981082420
Environment
expo v42.0.0
"react-native-pager-view": "5.4.0"
Description
Random onPress handle in FlatList items while swiping pages Especially noticeable on low-end android devices and in apps with many heavy components
Reproducible Demo
There is a function in demo that imitate CPU intensive operation in order for the issue to be stably reproduced in simple demo on high-end devices
https://snack.expo.dev/@sane.ecg/pager-onpress-issue
https://user-images.githubusercontent.com/764967/128613740-e384306f-a100-4b7c-9ade-7db12683d6e5.mp4