discussions-and-proposals
discussions-and-proposals copied to clipboard
PanResponder goes out of view
Discussed in https://github.com/react-native-community/discussions-and-proposals/discussions/427
Originally posted by NamrataDwivedi November 16, 2021
I have a requirement to make a section swipeable in left and right only. There are 3 views in my Class Component.

In the above image I have applied the PanResponder to Red box, but the effect is happening in whole Green portion of the UI.
`import React, { Component } from 'react'; import { StyleSheet, Text, View, Animated, Dimensions, PanResponder } from 'react-native'; import { connect } from "react-redux"; import CardError from '../../../assets/SVG/bankerror.svg'; import RightPolygon from "../../../assets/SVG/RightPolygon.svg"; import { FONT_FAMILY } from "@utils"; const SCREEN_HEIGHT = 140 const SCREEN_WIDTH = Dimensions.get('window').width
import React, { Component } from 'react'; import { StyleSheet, Text, View, Animated, Dimensions, PanResponder } from 'react-native'; import { connect } from "react-redux"; import CardError from '../../../assets/SVG/bankerror.svg'; import RightPolygon from "../../../assets/SVG/RightPolygon.svg"; import { FONT_FAMILY } from "@utils"; const SCREEN_HEIGHT = 140 const SCREEN_WIDTH = Dimensions.get('window').width
class TwitterSwipe extends Component {
constructor(props) {
super(props)
this.position = new Animated.ValueXY();
this.rotate = this.position.x.interpolate({
inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
outputRange: ['-30deg', '0deg', '10deg'],
extrapolate: 'clamp'
})
this.rotateAndTranslate = {
transform: [{
rotate: this.rotate
},
...this.position.getTranslateTransform()
]
}
this.state = {
currentIndex: 0,
listOfBanks: [
{
"title": "Title 1",
"description": " Description 1"
},
{
"title": "Title 2",
"description": " Description 2"
},
{
"title": "Title 3",
"description": " Description 3"
}
]
}
}
UNSAFE_componentWillMount() {
this.PanResponder = PanResponder.create({
onStartShouldSetPanResponder: (evt, gestureState) => true,
onPanResponderMove: (evt, gestureState) => {
},
onPanResponderRelease: (evt, gestureState) => {
console.log(evt)
if (gestureState.moveX == 0 && gestureState.moveY == 0) {
alert("clicked");
} else if (gestureState.dx > 120) {
Animated.spring(this.position, {
toValue: { x: SCREEN_WIDTH + 50, y: gestureState.dy }
}).start(() => {
this.setState({ currentIndex: this.state.currentIndex + 1 }, () => {
this.position.setValue({ x: 0, y: 0 })
})
})
}
else if (gestureState.dx < -120) {
Animated.spring(this.position, {
toValue: { x: -SCREEN_WIDTH - 50, y: gestureState.dy }
}).start(() => {
this.setState({ currentIndex: this.state.currentIndex + 1 }, () => {
this.position.setValue({ x: 0, y: 0 })
})
})
}
else {
Animated.spring(this.position, {
toValue: { x: 0, y: 0 },
friction: 4
}).start()
}
},
})
}
render() {
return (
<View style={{ height: this.state.currentIndex == this.state.listOfBanks.length ? 0 : 140 ,
marginBottom : this.state.currentIndex == this.state.listOfBanks.length ? 0 : 20
}}>
{this.renderCard()}
</View>
);
}
renderCard = () => {
return this.state.listOfBanks.map((item, i) => {
if (i < this.state.currentIndex) {
return null;
} else if (i == this.state.currentIndex) {
return (
<View>
<Animated.View
{...this.PanResponder.panHandlers}
key={i}
style={[
this.rotateAndTranslate,
{
height: SCREEN_HEIGHT,
width: "100%",
padding: 10,
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
marginTop: i * 5,
justifyContent: 'center',
alignItems: 'center'
}
]}
>
<View style={styles.mainContainerStyle}>
<View
style={{ flexDirection: "row" }}>
<View style={{ flex: 0.5 }}>
<CardError
height={24}
width={24}
/>
</View>
<View style={{
flex: 9, flexDirection: "column", marginStart: 20,
}}>
<Text
style={{
fontSize: 15,
fontWeight: "500",
lineHeight: 16,
color: "#1D1E1F",
fontFamily: FONT_FAMILY.SFProText,
}}
>{item.title}</Text>
<Text
style={{
fontSize: 13,
fontWeight: "400",
lineHeight: 16,
color: "#91919F",
fontFamily: FONT_FAMILY.SFProText,
marginTop: 10
}}
>{item.description} </Text>
</View>
<View style={{ flex: 0.5 }} >
<RightPolygon
height={15}
width={15}
style={{ marginRight: 3 }}
/>
</View>
</View>
</View>
</Animated.View>
</View>
)
} else {
return (
<View>
<Animated.View
key={i}
style={[
{
height: SCREEN_HEIGHT,
width: "100%",
padding: 10,
position: 'absolute',
top: 0,
left: 0,
right: 0,
bottom: 0,
marginTop: i * 5,
justifyContent: 'center',
alignItems: 'center'
}
]}
>
<View style={styles.mainContainerStyle}>
<View
style={{ flexDirection: "row" }}>
<View style={{ flex: 0.5 }}>
<CardError
height={24}
width={24}
/>
</View>
<View style={{
flex: 9, flexDirection: "column", marginStart: 20,
}}>
<Text
style={{
fontSize: 15,
fontWeight: "500",
lineHeight: 16,
color: "#1D1E1F",
fontFamily: FONT_FAMILY.SFProText,
}}
>{item.title}</Text>
<Text
style={{
fontSize: 13,
fontWeight: "400",
lineHeight: 16,
color: "#91919F",
fontFamily: FONT_FAMILY.SFProText,
marginTop: 10
}}
>{item.description} </Text>
</View>
</View>
</View>
</Animated.View>
</View>
)
}
}).reverse();
}
}
Above code is for the red box. I am just rendering this UI in another Component class.
My requirement is to just make the red box items swipeable in left and right.
Help would be appreciated.