Closed diego-paired closed 2 years ago
"react-native-reanimated": "2.2.4", "react-native-reanimated-carousel": "^2.3.2", "react-native-gesture-handler": "^2.3.2",
I'm using the Carousel in its default mode horizontally scrolling. When the items rendered use Pressable and the user scrolls horizontally, the scroll happens but a press is also registered when lifting the finger. If I swap Pressable for a Gesture Handler Touchable, the error disappears.
Please advise, thank you.
Can you show me a video, I can't imagine what it looks like
When pressing to scroll sideways, the pressable is also triggered and navigates to the content of the card
hmm... show me your code?
Does that happen if you run my demo code(In homepage)?
Hi @diego-paired and @dohooo, To give maybe a hint, In my case, I have the same problem only with Android when the carousel is under a modal, otherwise the carousel works fine. The problem appear when the carousel is under a modal with a touchable opacity (from react-native library or gesture handler is the same), but i can't scroll the carousel in my case, the onPress action trigger immediately .
The Component under modal
`import React, { useRef } from 'react';
import { Image, View, TouchableOpacity, Text, Dimensions } from "react-native";
import Carousel from 'react-native-reanimated-carousel';
import { colors } from "../utils/const";
import { isIphoneX } from '../utils/isIphoneX';
import { FoodTruckItem } from './Home/FoodTruckItemComponent';
const manPicture = require('../assets/man.png')
export function OrderCancelComponent({ carouselItems, openMenu, closeModal }) {
const carouseOrderCancellRef = useRef();
return (
<View style={{ flex: 1, height: '100%', width: '100%', alignItems: 'center', backgroundColor: 'white' }}>
<View style={{ height: '60%', width: '80%', justifyContent: 'flex-end' }}>
<Image style={{ height: '40%', width: '100%', resizeMode: 'contain' }} source={manPicture}></Image>
<Text style={{ fontSize: 24, fontWeight: 'bold', fontFamily: 'Poppins', color: colors.blueText, width: '100%', textAlign: 'center', marginTop: 20 }}>Oups! Ce véhicule n’est pas disponible</Text>
<Text style={{ fontSize: 18, fontWeight: '500', fontFamily: 'Poppins', color: colors.blueText, width: '100%', textAlign: 'center', marginTop: 20 }}>Pas de panique, d’autres t’attendent, jette un coup d’oeil à nos suggestions 👇</Text>
</View>
<View style={{ flex: 1, paddingBottom: isIphoneX() ? 20 : 0, height: '40%', width: '100%', justifyContent: 'flex-end', alignItems: 'center' }}>
<Text style={{ fontSize: 16, fontWeight: 'bold', fontFamily: 'Poppins', color: 'black', width: '90%', textAlign: 'left' }}>Nos suggestions :</Text>
<View style={{ height: 120, width: '100%', justifyContent: 'center', alignItems: 'center' }}>
<Carousel
ref={carouseOrderCancellRef}
width={Dimensions.get('screen').width}
height={120}
data={carouselItems}
renderItem={({ item }) => <FoodTruckItem item={item} openMenuTapped={() => openMenu(item, false)}></FoodTruckItem>}
// onSnapToItem={(index) => setMarkerSelected(index)}
// onScrollEnd={(prev, current) => setMarkerSelected(current)}
loop={true}
mode={"parallax"}
modeConfig={{ parallaxScrollingScale: 1, parallaxScrollingOffset: 60 }}
/>
</View>
<TouchableOpacity onPress={closeModal} style={{ height: 52, width: '90%', marginTop: 15, marginBottom: 15, justifyContent: 'center', alignItems: 'center', backgroundColor: colors.orange, borderRadius: 10}}>
<Text style={{ fontSize: 16, fontWeight: 'bold', color: 'white' }}>Voir la carte</Text>
</TouchableOpacity>
</View>
</View>
);
}`
The carousel item component
`import React from 'react';
import { Image, View, Text, Dimensions, TouchableOpacity } from "react-native";
import { colors } from "../../utils/const";
import { sharedStyles } from '../../utils/styles';
const halalIcon = require('../../assets/home/halalFood.png')
const screenWidth = Dimensions.get('screen').width
export function FoodTruckItem({ item, openMenuTapped }) {
return (
<View style={{ height: 120, width: screenWidth * 0.9, justifyContent: 'center', alignItems: 'center' }}>
<TouchableOpacity activeOpacity={1} onPress={openMenuTapped} style={{ ...sharedStyles.shadow, shadowRadius: 5, height: 110, width: '90%', borderRadius: 10, backgroundColor: 'white' }}>
<View style={{ height: '100%', width: '100%', flexDirection: 'row' }}>
<View style={{ height: '100%', width: '30%', justifyContent: 'center', alignItems: 'center' }}>
<Image source={{ uri: item.truckDetails.logo }} style={{ height: '80%', width: '80%', resizeMode: 'contain' }}></Image>
</View>
<View style={{ height: '100%', width: '70%' }}>
<View style={{ height: '60%', width: '100%', justifyContent: 'center', alignItems: 'flex-start' }}>
{item.truckDetails.halal &&
< Image source={halalIcon} style={{ flex: 1, position: 'absolute', top: 5, right: 10, resizeMode: 'contain', height: 40, width: 40 }}></Image>
}
<Text style={{ fontSize: 18, fontWeight: 'bold', color: 'black', width: '70%' }}>{item.truckDetails.name} •</Text>
<Text style={{ fontSize: 16, fontWeight: 'normal', color: 'black', width: '80%' }}>{item.truckDetails.short_description}</Text>
</View>
<View style={{ height: '40%', width: '100%', justifyContent: 'center', alignItems: 'flex-start' }}>
<View>
<Text style={{ fontSize: 16, fontWeight: 'normal', color: colors.orange, textDecorationLine: 'underline' }}>Voir le menu</Text>
</View>
</View>
</View>
</View>
</TouchableOpacity>
</View >
);
}`
My package json
`{
"name": "foodrivrepo",
"version": "0.0.1",
"private": true,
"scripts": {
"android": "react-native run-android",
"ios": "react-native run-ios",
"start": "react-native start",
"test": "jest",
"lint": "eslint ."
},
"dependencies": {
"@gorhom/bottom-sheet": "^4.1.5",
"@react-native-async-storage/async-storage": "^1.17.0",
"@react-native-firebase/analytics": "^14.7.0",
"@react-native-firebase/app": "^14.7.0",
"@react-native-firebase/auth": "^14.7.0",
"@react-native-firebase/database": "^14.7.0",
"@react-native-firebase/firestore": "^14.7.0",
"@react-native-firebase/functions": "^14.7.0",
"@react-native-firebase/messaging": "^14.7.0",
"@react-native-masked-view/masked-view": "^0.2.6",
"@react-navigation/drawer": "^6.3.3",
"@react-navigation/elements": "^1.3.1",
"@react-navigation/native": "^6.0.8",
"@react-navigation/stack": "^6.1.1",
"axios": "^0.26.1",
"react": "17.0.2",
"react-native": "0.67.4",
"react-native-anchor-carousel": "^4.0.1",
"react-native-date-picker": "^4.2.0",
"react-native-fast-image": "^8.5.11",
"react-native-geolocation-service": "^5.3.0-beta.4",
"react-native-gesture-handler": "2.3.2",
"react-native-google-places-autocomplete": "^2.4.1",
"react-native-image-pan-zoom": "^2.1.12",
"react-native-image-viewing": "^0.2.1",
"react-native-image-zoom-viewer": "^3.0.1",
"react-native-keyboard-aware-scroll-view": "^0.9.5",
"react-native-maps": "0.30.1",
"react-native-modal": "^13.0.1",
"react-native-permissions": "^3.3.1",
"react-native-phone-number-input": "^2.1.0",
"react-native-reanimated": "^2.5.0",
"react-native-reanimated-carousel": "^2.3.2",
"react-native-safe-area-context": "^4.2.4",
"react-native-screens": "^3.13.1",
"react-native-snap-carousel": "^3.9.1"
},
"devDependencies": {
"@babel/core": "^7.17.8",
"@babel/runtime": "^7.17.8",
"@react-native-community/eslint-config": "^3.0.1",
"babel-jest": "^27.5.1",
"eslint": "8.12.0",
"jest": "^27.5.1",
"metro-react-native-babel-preset": "^0.70.0",
"react-test-renderer": "17.0.2"
},
"jest": {
"preset": "react-native"
}
}
I hope this will help you !
Hi @diego-paired and @dohooo, To give maybe a hint, In my case, I have the same problem only with Android when the carousel is under a modal, otherwise the carousel works fine. The problem appear when the carousel is under a modal with a touchable opacity (from react-native library or gesture handler is the same), but i can't scroll the carousel in my case, the onPress action trigger immediately .
The Component under modal
`import React, { useRef } from 'react'; import { Image, View, TouchableOpacity, Text, Dimensions } from "react-native"; import Carousel from 'react-native-reanimated-carousel'; import { colors } from "../utils/const"; import { isIphoneX } from '../utils/isIphoneX'; import { FoodTruckItem } from './Home/FoodTruckItemComponent';
const manPicture = require('../assets/man.png')
export function OrderCancelComponent({ carouselItems, openMenu, closeModal }) {
const carouseOrderCancellRef = useRef(); return ( <View style={{ flex: 1, height: '100%', width: '100%', alignItems: 'center', backgroundColor: 'white' }}> <View style={{ height: '60%', width: '80%', justifyContent: 'flex-end' }}> <Image style={{ height: '40%', width: '100%', resizeMode: 'contain' }} source={manPicture}></Image> <Text style={{ fontSize: 24, fontWeight: 'bold', fontFamily: 'Poppins', color: colors.blueText, width: '100%', textAlign: 'center', marginTop: 20 }}>Oups! Ce véhicule n’est pas disponible</Text> <Text style={{ fontSize: 18, fontWeight: '500', fontFamily: 'Poppins', color: colors.blueText, width: '100%', textAlign: 'center', marginTop: 20 }}>Pas de panique, d’autres t’attendent, jette un coup d’oeil à nos suggestions 👇</Text> </View> <View style={{ flex: 1, paddingBottom: isIphoneX() ? 20 : 0, height: '40%', width: '100%', justifyContent: 'flex-end', alignItems: 'center' }}> <Text style={{ fontSize: 16, fontWeight: 'bold', fontFamily: 'Poppins', color: 'black', width: '90%', textAlign: 'left' }}>Nos suggestions :</Text> <View style={{ height: 120, width: '100%', justifyContent: 'center', alignItems: 'center' }}> <Carousel ref={carouseOrderCancellRef} width={Dimensions.get('screen').width} height={120} data={carouselItems} renderItem={({ item }) => <FoodTruckItem item={item} openMenuTapped={() => openMenu(item, false)}></FoodTruckItem>} // onSnapToItem={(index) => setMarkerSelected(index)} // onScrollEnd={(prev, current) => setMarkerSelected(current)} loop={true} mode={"parallax"} modeConfig={{ parallaxScrollingScale: 1, parallaxScrollingOffset: 60 }} /> </View> <TouchableOpacity onPress={closeModal} style={{ height: 52, width: '90%', marginTop: 15, marginBottom: 15, justifyContent: 'center', alignItems: 'center', backgroundColor: colors.orange, borderRadius: 10}}> <Text style={{ fontSize: 16, fontWeight: 'bold', color: 'white' }}>Voir la carte</Text> </TouchableOpacity> </View> </View> );
}`
The carousel item component
`import React from 'react'; import { Image, View, Text, Dimensions, TouchableOpacity } from "react-native"; import { colors } from "../../utils/const"; import { sharedStyles } from '../../utils/styles';
const halalIcon = require('../../assets/home/halalFood.png') const screenWidth = Dimensions.get('screen').width
export function FoodTruckItem({ item, openMenuTapped }) { return ( <View style={{ height: 120, width: screenWidth * 0.9, justifyContent: 'center', alignItems: 'center' }}> <TouchableOpacity activeOpacity={1} onPress={openMenuTapped} style={{ ...sharedStyles.shadow, shadowRadius: 5, height: 110, width: '90%', borderRadius: 10, backgroundColor: 'white' }}> <View style={{ height: '100%', width: '100%', flexDirection: 'row' }}> <View style={{ height: '100%', width: '30%', justifyContent: 'center', alignItems: 'center' }}> <Image source={{ uri: item.truckDetails.logo }} style={{ height: '80%', width: '80%', resizeMode: 'contain' }}> <View style={{ height: '100%', width: '70%' }}> <View style={{ height: '60%', width: '100%', justifyContent: 'center', alignItems: 'flex-start' }}> {item.truckDetails.halal && < Image source={halalIcon} style={{ flex: 1, position: 'absolute', top: 5, right: 10, resizeMode: 'contain', height: 40, width: 40 }}> } <Text style={{ fontSize: 18, fontWeight: 'bold', color: 'black', width: '70%' }}>{item.truckDetails.name} • <Text style={{ fontSize: 16, fontWeight: 'normal', color: 'black', width: '80%' }}>{item.truckDetails.short_description} <View style={{ height: '40%', width: '100%', justifyContent: 'center', alignItems: 'flex-start' }}> <Text style={{ fontSize: 16, fontWeight: 'normal', color: colors.orange, textDecorationLine: 'underline' }}>Voir le menu ); }`
My package json
{ "name": "foodrivrepo", "version": "0.0.1", "private": true, "scripts": { "android": "react-native run-android", "ios": "react-native run-ios", "start": "react-native start", "test": "jest", "lint": "eslint ." }, "dependencies": { "@gorhom/bottom-sheet": "^4.1.5", "@react-native-async-storage/async-storage": "^1.17.0", "@react-native-firebase/analytics": "^14.7.0", "@react-native-firebase/app": "^14.7.0", "@react-native-firebase/auth": "^14.7.0", "@react-native-firebase/database": "^14.7.0", "@react-native-firebase/firestore": "^14.7.0", "@react-native-firebase/functions": "^14.7.0", "@react-native-firebase/messaging": "^14.7.0", "@react-native-masked-view/masked-view": "^0.2.6", "@react-navigation/drawer": "^6.3.3", "@react-navigation/elements": "^1.3.1", "@react-navigation/native": "^6.0.8", "@react-navigation/stack": "^6.1.1", "axios": "^0.26.1", "react": "17.0.2", "react-native": "0.67.4", "react-native-anchor-carousel": "^4.0.1", "react-native-date-picker": "^4.2.0", "react-native-fast-image": "^8.5.11", "react-native-geolocation-service": "^5.3.0-beta.4", "react-native-gesture-handler": "2.3.2", "react-native-google-places-autocomplete": "^2.4.1", "react-native-image-pan-zoom": "^2.1.12", "react-native-image-viewing": "^0.2.1", "react-native-image-zoom-viewer": "^3.0.1", "react-native-keyboard-aware-scroll-view": "^0.9.5", "react-native-maps": "0.30.1", "react-native-modal": "^13.0.1", "react-native-permissions": "^3.3.1", "react-native-phone-number-input": "^2.1.0", "react-native-reanimated": "^2.5.0", "react-native-reanimated-carousel": "^2.3.2", "react-native-safe-area-context": "^4.2.4", "react-native-screens": "^3.13.1", "react-native-snap-carousel": "^3.9.1" }, "devDependencies": { "@babel/core": "^7.17.8", "@babel/runtime": "^7.17.8", "@react-native-community/eslint-config": "^3.0.1", "babel-jest": "^27.5.1", "eslint": "8.12.0", "jest": "^27.5.1", "metro-react-native-babel-preset": "^0.70.0", "react-test-renderer": "17.0.2" }, "jest": { "preset": "react-native" } }
I hope this will help you !
Could you give me an REPO or EXPO link? It'll make it easier for me to deal with your problem.
Hi again, sorry for the late answer i found the solution !
In my case it's because of the modal, explanation just below:
`Usage with modals on Android#
On Android RNGH does not work by default because modals are not located under React Native Root view in native hierarchy. In order to make it workable, components need to be wrapped with gestureHandlerRootHOC (it's no-op on iOS and web).
E.g.
const ExampleWithHoc = gestureHandlerRootHOC(function GestureExample() {
return (
<View>
<DraggableBox />
</View>
);
});
export default function Example() {
return (
<Modal animationType="slide" transparent={false}>
<ExampleWithHoc />
</Modal>
);
}`
Hope this will help someone maybe ! Link to react native gesture handler doc : https://docs.swmansion.com/react-native-gesture-handler/docs/installation/#usage-with-modals-on-android
currently experiencing the same. just migrated from react-native-snap-carousel, but am facing this issue that i just can't figure out how to fix. i also get a warning that my react-native-gesture-handler is using an old api version, which may have something to do with it. i'm using a bare react-native app, tested on both Android and iOS, with Pressable and TouchOpacity, and both trigger the onPress function when scrolling. I'm not using the modal component, by the way
Maybe try to add gestureHandlerRootHOC on your component and use TouchOpacity from react-native-gesture-handler inside your carousel item.
About the warning i don't know exactly what is it, but after some research it seems to be nothing important. In my case i remove the warning message by downgrading to "react-native-gesture-handler": "2.1.1". but keep in mind that this is only a warning.
If you use react navigation library, it's maybe because of @react-navigation/stack using old api version. Now they use native stack @react-navigation/native-stack
@diego-paired @halaxysounds
I have reproduced your problem. I used the same version. @diego-paired
"react-native-reanimated": "2.2.4",
"react-native-reanimated-carousel": "^2.3.2",
"react-native-gesture-handler": "^2.3.2",
// will be trigger the onPress function when scrolling
import { TouchableOpacity } from 'react-native';
// will be fine
import { TouchableOpacity } from 'react-native-gesture-handler';
Can you give it a try and let me know the result? I believe this is solvable, because most people haven't talked to me about this kind of problem, and they've obviously used the solution here.
When I changed to TouchableOpacity of RNGH
, the error no longer appeared.
Is there an answer for this that does not use TouchableOpacity
from react-native-gesture-handler
? It is not fully compatible with React Native's TouchableOpacity
and will not work in my use case.
Does react-native-reanimated-carousel
not work with TouchableOpacity
components nested inside?
Is there an answer for this that does not use
TouchableOpacity
fromreact-native-gesture-handler
? It is not fully compatible with React Native'sTouchableOpacity
and will not work in my use case.Does
react-native-reanimated-carousel
not work withTouchableOpacity
components nested inside?
What's your mean? If you have any other questions. I suggest you create a new issue.
The TouchableOpacity
component provided by react-native-gesture-handler
is not a drop-in replacement for React Native's TouchableOpacity
component. It behaves differently and handles styling differently. I'm unfortunately not able to use their TouchableOpacity
component as was suggested in this ticket. But I'm still having the same problem as the original poster in this ticket. That is, when I have a component inside of a carousel, swiping left/right is also registered as a tap event by TouchableOpacity
, erroniously. Is there any other way around this issue?
The
TouchableOpacity
component provided byreact-native-gesture-handler
is not a drop-in replacement for React Native'sTouchableOpacity
component. It behaves differently and handles styling differently. I'm unfortunately not able to use theirTouchableOpacity
component as was suggested in this ticket. But I'm still having the same problem as the original poster in this ticket. That is, when I have a component inside of a carousel, swiping left/right is also registered as a tap event byTouchableOpacity
, erroniously. Is there any other way around this issue?
Sry I don't know. Maybe you can create a discussion for this question.
The
TouchableOpacity
component provided byreact-native-gesture-handler
is not a drop-in replacement for React Native'sTouchableOpacity
component. It behaves differently and handles styling differently. I'm unfortunately not able to use theirTouchableOpacity
component as was suggested in this ticket. But I'm still having the same problem as the original poster in this ticket. That is, when I have a component inside of a carousel, swiping left/right is also registered as a tap event byTouchableOpacity
, erroniously. Is there any other way around this issue?
Infact I don’t think it related to this library, and I think you can find some inspiration from documentation in react-native-gesture-handler library.
Hey there, thanks for this amazing library. I am still facing this issue
@diego-paired @halaxysounds
I have reproduced your problem. I used the same version. @diego-paired
"react-native-reanimated": "2.2.4", "react-native-reanimated-carousel": "^2.3.2", "react-native-gesture-handler": "^2.3.2",
// will be trigger the onPress function when scrolling import { TouchableOpacity } from 'react-native'; // will be fine import { TouchableOpacity } from 'react-native-gesture-handler';
Can you give it a try and let me know the result? I believe this is solvable, because most people haven't talked to me about this kind of problem, and they've obviously used the solution here.
Thank you! You save my life 😆
I'm using the Carousel in its default mode horizontally scrolling. When the items rendered use Pressable and the user scrolls horizontally, the scroll happens but a press is also registered when lifting the finger. If I swap Pressable for a Gesture Handler Touchable, the error disappears.
Please advise, thank you.