react-native-swiper
react-native-swiper copied to clipboard
Not getting correct index
Which OS ?
Both iOS and Android
Version
Which versions are you using:
- react-native-swiper v? 1.6.0
- react-native v0.?.? 0.63.3
Expected behaviour
Neither onMomentumScrollEnd nor onIndexChanged would give the correct index. Resulting in unpredictable behavior
Actual behaviour
Random results and unusable indexes. After swiping 4-6 times I will usually be delivered the value -1. Created the following function to get the correct index:
calculateIndex(nativeEvent) {
if (!nativeEvent) {
return 0
}
if (!nativeEvent.layoutMeasurement) {
return 0
}
if (!nativeEvent.contentOffset) {
return 0
}
const screenWidth = nativeEvent.layoutMeasurement.width
const xOffset = nativeEvent.contentOffset.x
const index = xOffset / screenWidth
return index
}
How to reproduce it>
<Swiper
horizontal={true}
width={c.WIN_WIDTH}
height={c.WIN_HEIGHT}
index={this.state.currentIndex}
scrollEnabled={true}
loadMinimal={false}
showsPagination={false}
pagingEnabled
automaticallyAdjustContentInsets
onMomentumScrollEnd={this.onMomentumScrollEnd}
bounces={true}
loop={false}
autoplay={false}
showsButtons={false}
removeClippedSubviews={false}>
<View style={styles.slide1}>
<Text style={styles.text}>Hello Swiper</Text>
</View>
<View style={styles.slide2}>
<Text style={styles.text}>Beautiful</Text>
</View>
<View style={styles.slide3}>
<Text style={styles.text}>And simple</Text>
</View>
</Swiper>
Steps to reproduce
@pospetur From the code you shared I'm guessing you are trying to change the page according to the index with state. This approach has gotten me into several issues, such as pagination showing wrong active dot, and so on. This approach might be the issue you are facing. I advice you to move between pages using ref and ref.current.scrollBy(value).
ref.current.scrollBy(1)
==> moves the page forward once.
ref.current.scrollBy(-1)
==> moves the page backward once.
In my case I still keep a state for index [currentScreen]. I will share some code and hope it helps!
const [currentScreen, setCurrentScreen] = useState(0); // 0, 1, 2, 3, etc for the pages respectively
const swipeRef = useRef(null);
// function called on previous button
const onBackward = (): void => {
if (currentScreen > 0) {
swipeRef.current?.scrollBy(-1); // go back one page
setCurrentScreen((prevState) => prevState - 1);
} else {
navigation.goBack(); // or some other logic for you
}
};
// function called on next button
const onForward = (): void => {
if (currentScreen < TOTAL_NUMBER_OF_PAGES) { // actually TOTAL_NUMBER_OF_PAGES -1 will be the last pages index
swipeRef.current?.scrollBy(1); // go forward one page
setCurrentScreen((prevState) => prevState + 1);
} else {
navigation.navigate('Next Screen through navigation')
}
};
<Swiper
loop={false}
ref={swipeRef}
scrollEnabled={false}
showsPagination={false}
keyboardShouldPersistTaps="handled"
>
By doing so, the index will be correct also.
@JayantJoseph Thank you for your answer. Your solution is better than mine. But it still leaves the issue open.
@pospetur did you ever resolve this?