Reputation: 525
I am trying to make a tinder like swipe functionality using a functional component.
I've essentially made a functional version of the below tutorial
https://www.instamobile.io/react-native-controls/react-native-swipe-cards-tinder/
However I am having a weird issue where it would appear the state of the card to display doesn't get updated properly. The first time it seems to work but from then on wards it always seems to return 0
I've made a video to illustrate the weird behaviour
import React, {useState, useEffect, useRef} from "react";
import { StyleSheet, View, Text, TouchableOpacity, Image, ImageBackground, Animated, PanResponder,Dimensions } from "react-native";
import { LinearGradient } from 'expo-linear-gradient';
import { StatusBar } from 'expo-status-bar';
import QuestionBox from "../Components/questionBox.js"
import {styles} from "./questionStyles.js"
const SCREEN_HEIGHT = Dimensions.get('window').height
const SCREEN_WIDTH = Dimensions.get('window').width
function QuestionScreen({route, navigation}) {
const {players, mode} = route.params;
const [questions, setQuestions]=useState([
{title:"Dare", text:"boooooooooooo"},
{title:"Question", text:"fdoooooo"},
{title:"Question", text:"fdfsfsfsfsfsfsoooooo"},
{title:"Dare", text:"bodfooo"}
]);
const pan = useRef(new Animated.ValueXY()).current;
const [currentIndex, setIndex] =useState(0);
const [times, setTimes]=useState(0)
const panResponder = useRef(
PanResponder.create({
onMoveShouldSetPanResponder: (evt, gestureState) => true,
onPanResponderMove: Animated.event([null, { dx: pan.x, dy: pan.y }],{useNativeDriver: false}) ,
onPanResponderRelease: (evt, gestureState) => {
pan.flattenOffset();
},
onPanResponderRelease: (evt, gestureState) => {
if (gestureState.dx > 120 ) {
Animated.spring(pan, {
toValue: { x: SCREEN_WIDTH + 100, y: gestureState.dy },
useNativeDriver: true
}).start(()=>{
setIndex(currentIndex+1)
pan.setValue({ x: 0, y: 0 })
console.log("value of current index is: ".concat(currentIndex) )
})
}
else {
Animated.spring(pan, {
toValue: { x: 0, y: 0 },
useNativeDriver: true,
friction: 4
}).start()
}
}
})
).current;
const rotate = pan.x.interpolate({
inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
outputRange: ['-10deg', '0deg', '10deg'],
extrapolate: 'clamp'
})
const rotateAndTranslate= {
transform: [{rotate:rotate},{ translateX: pan.x }, { translateY: pan.y }]
}
const nextOpacity = pan.x.interpolate({
inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
outputRange: [0, 0, 1],
extrapolate: 'clamp'
})
const nextCardOpacity = pan.x.interpolate({
inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
outputRange: [1, 0, 1],
extrapolate: 'clamp'
})
const nextCardScale = pan.x.interpolate({
inputRange: [-SCREEN_WIDTH / 2, 0, SCREEN_WIDTH / 2],
outputRange: [1, 0.8, 1],
extrapolate: 'clamp'
})
const renderQuestions = () => {
return questions.map((item, i) => {
if (i < currentIndex) {
return null
} else if (i === currentIndex) {
return (
<Animated.View
key={i}
style={[rotateAndTranslate,{
height: "100%",
width: "100%",
flex:1 ,
zIndex:1000,
elevation:10,
position:"absolute",
flexDirection:"column"}]}
{...panResponder.panHandlers}
>
<Animated.View
style={{
transform: [{ rotate: "20deg" }],
position: "absolute",
top: 20,
right: 20,
zIndex: 1000,
elevation:100,
opacity:nextOpacity
}}
>
<Text
style={{
borderWidth: 1,
borderColor: "#dd3fac",
color: "#dd3fac",
fontSize: 32,
fontWeight: "800",
padding: 10
}}
>
NEXT >>
</Text>
</Animated.View>
<QuestionBox title={item.title} text={item.text} />
</Animated.View>
);
}else {
return (
<Animated.View
key={i}
style={{
height: "100%",
width: "100%",
flex:1 ,
position:"absolute",
flexDirection:"column",
opacity: nextCardOpacity,
transform: [{ scale: nextCardScale }]
}}
>
<QuestionBox title={item.title} text={item.text} />
</Animated.View>
);
}
}).reverse();
};
return(
<>
<StatusBar
translucent={true} />
<ImageBackground source={vertBackground} style={styles.image}/>
<View style={styles.container}>
<View style={styles.spacer1} />
<View style={{flex:4.6, width:"100%", height:"100%"}}>
{renderQuestions()}
</View>
<View style={styles.spacer1} / >
</View>
</>
);
}
export default QuestionScreen;
Upvotes: 0
Views: 136
Reputation: 653
Try set the index like this:
setIndex(currentIndexValue => currentIndexValue+1);
Upvotes: 1