Open fatonramadani opened 8 years ago
+1
+1
I solve this by passing props to the Swiper component, and calling scrollTo in componentWillReceiveProps accordingly.
@drrazor can you share a code example?
@PimDeWitte I had the same problem and I solve it exactly like @DrRazor said. Some sample code:
Setup your swiper like this:
<Swiper style={styles.wrapper} yourNewPageIndex={this.state.newIndex}>
then with the button that you want to trigger the swipe:
<Button onPress={() => this.setState({newIndex: 2})}/>
then in the swiper module change the componentWillReceiveProps like this:
componentWillReceiveProps(props) {
this.setState(this.initState(props));
if(props.yourNewPageIndex){
this.scrollBy(props.yourNewPageIndex)
}
}
that's it... It works for me. I hope it works for you.
@luiscript thank you!
+1 We should have a prop like current page or something like that.
I did with ref. Sample code:
<Swiper ref='swiper' style={welcome.wrapper} showsButtons={false} loop={false} >
Then in the button.
onPress={() => this.refs.swiper.scrollBy(1)}
I've achieved the same way @gferreyra91 did. I believe this is the best solution since updating the state with the new index and calling scrolling by with the new index seems to be doing the same thing.
I'm having issues however when the number of pages in the swiper is updated: scrollBy does not work unless I manually scroll the view.
Can you also pass this ref to a child component? So they can have buttons that trigger the Swiper parent?
@YannisDC Did you figure out a way to pass it to the child component and scrolling accordingly?
Doesn't works with loadMinimal = true
@gferreyra91
Because this still shows in Google Search results I'll add a bit on @gferreyra91 's solution. I don't think refs
are long for this world, but it's still a fine solution for issues like this.
There is no need to pass the ref to the children as @rahls7 and @YannisDC suggest. I think it's much cleaner to handle the ref in its owner, and pass a function:
I define this method on the Swiper's parent:
swipe(n) {
swiper = this.refs.swiper
if (swiper) swiper.scrollBy(n || 1)
}
And then, in the Items:
<Item
onPrevious={() => this.swipe(-1)}
onNext={() => this.swipe(1)}
/>
As @gferreyra91 said, you have to assign the ref to the Swiper component:
<Swiper ref="swiper" {...otherProps}>{ pages }</Swiper>
PD: In spite of what @zawars comments, this is working fine for me with loadMinimal
and loadMinimalSize={2}
. May be they fixed that already.
@YannisDC @gferreyra91
You could add a function prop for the child element.
e.g.
this.swiper = undefined;
<Swiper ref=(e => this.swiper = e) {...otherProps}>
<View>
<Child getSwiper={() => this.swiper} />
</View>
</Swiper>
In this way, in the child component, you will be able to invoke:
this.props.getSwiper().scrollBy(1);
The mentioned solution is pretty anti-pattern to be honest. The index property of Swiper should be observable. There are already warnings in RN 0.6.
Using React Hooks, this code bellow worked for me:
const swiper = useRef(null)
<Swiper
ref={swiper}
{...OtherProps}>
</Swiper>
<Button onPress={() => swiper.current.scrollTo(1) }/>
the mentioned anti-pattern it's true, you should pass actions instead of references/instances:
export default function SwiperComponent({}) {
const swiperRef = useRef(null);
const next = () => {
if (!!swiperRef) {
swiperRef.current.scrollBy(1);
}
};
return <Swiper ref={swiperRef}>
<ChildOne onNextPressed={() => next()} />
<ChildTwo onNextPressed={() => next()} />
<ChildThree onNextPressed={() => next()} />
</Swiper>;
}
Children should do something like this (for example):
export default function ChildOne({onNextPressed}) {
return <Button onPress={onNextPressed} />;
}
navigation={{ prevEl: '.classname-of-button-prev', nextEl: '.classname-of-button-next', }}
How can I trigger a swipe ( Left/Right) with a button ?