Reputation: 159
The swiper index value comes out in order of page order. However, when the button is pressed, the index value goes up to infinity.
ex) next button click-> 6/5, 7/5, 8/5
What I would like to do is stop the button event on 5/5 but I do not know what to do.
https://github.com/leecade/react-native-swiper
App.js
const renderPagination = (index, total, context) => {
return (
<View style={styles.paginationStyle}>
<Text style={{ color: 'grey' }}>
<Text style={styles.paginationText}>{index + 1}</Text>/{total}
</Text>
</View>
)
}
export default class App extends Component {
constructor(props){
super(props);
this.onPressNext = this.onPressNext.bind(this);
this.state = {
idxActive: 1
}
}
onPressPrev = () => {
this.refs.swiper.scrollBy(-1)
}
onPressNext = () => {
this.refs.swiper.scrollBy(1);
}
render() {
return (
<View style={styles.container}>
<Swiper
style={styles.wrapper}
renderPagination={renderPagination}
showsButtons={false}
loop={false}
ref={'swiper'}
>
<View style={styles.slide}>
<Text style={styles.text}>1 page</Text>
</View>
<View style={styles.slide}>
<Text style={styles.text}>2 page</Text>
</View>
<View style={styles.slide}>
<Text style={styles.text}>3 page</Text>
</View>
<View style={styles.slide}>
<Text style={styles.text}>4 page</Text>
</View>
<View style={styles.slide}>
<Text style={styles.text}>5 page</Text>
</View>
</Swiper>
<View style={styles.buttoncontainer}>
<Button
onPress={this.onPressPrev}
title="previous">
</Button>
<Button
onPress={this.onPressNext}
title="next">
</Button>
</View>
</View>
);
}
}
Upvotes: 6
Views: 9329
Reputation: 11
here's what helped me, use onIndexChanged prop in swiper, it keeps track of your swiper elements length, the following code snippet is for a functional component.
const [keyNumber, setKeyNumber] = useState(0);
const swiperRef = useRef(null);
const isPrevDisabled = keyNumber < 1;
const isNextDisabled = keyNumber > calloutScreens.length - 2;
const renderPrevButton = () => {
return (
<TouchableOpacity
style={styles.buttonWrapper}
disabled={isPrevDisabled}
onPress={() => swiperRef.current?.scrollBy(-1)}>
<Text
style={isPrevDisabled ? styles.disabledButton :
styles.activeButton}>
{PREVIOUS}
</Text>
</TouchableOpacity>
);
};
const renderNextButton = () => {
return (
<TouchableOpacity
style={styles.buttonWrapper}
disabled={isNextDisabled}
onPress={() => swiperRef.current?.scrollBy(1)}>
<Text
style={isNextDisabled ? styles.disabledButton :
styles.activeButton}>
{NEXT}
</Text>
</TouchableOpacity>
);
};
const handleIndexChange = (index: number) => {
setKeyNumber(index);
};
return (
<View style={styles.container}>
{calloutScreens.length > 0 && (
<>
<Swiper
autoplay={true}
ref={swiperRef}
autoplayTimeout={5}
loop={false}
activeDotStyle={styles.activeDotStyle}
dotStyle={styles.inactiveDotStyle}
showsPagination={true}
onIndexChanged={handleIndexChange}>
{renderSwiperContent()}
</Swiper>
<View style={styles.footerContainer}>
{renderPrevButton()}
<HKButton
title={BUTTON_TITLE}
onPress={handleOnboardingCompletion}
/>
{renderNextButton()}
</View>
</>
)}
Upvotes: 1
Reputation: 6052
Use the onIndexedChanged
prop of the swiper to get the latest index
and save it in your local component state. Something like:
export default class App extends Component {
constructor(props){
super(props);
this.onPressNext = this.onPressNext.bind(this);
this.onPressPrev = this.onPressPrev.bind(this);
this.state = {
idxActive: 0
}
}
onPressPrev = () => {
const {idxActive} = this.state;
if (idxActive > 0) {
this.refs.swiper.scrollBy(-1)
}
}
onPressNext = () => {
const {idxActive} = this.state;
// Probably best set as a constant somewhere vs a hardcoded 5
if (idxActive < 5) {
this.refs.swiper.scrollBy(1);
}
}
render() {
return (
<View style={styles.container}>
<Swiper
... etc.
onIndexChanged={idxActive => this.setState({idxActive})}
>
... etc.
Upvotes: 4