leecade / react-native-swiper

The best Swiper component for React Native.
MIT License
10.42k stars 2.34k forks source link

Trigger swipe with a button #111

Open fatonramadani opened 8 years ago

fatonramadani commented 8 years ago

How can I trigger a swipe ( Left/Right) with a button ?

Kim-Andersen commented 8 years ago

+1

PimDeWitte commented 8 years ago

+1

fatonramadani commented 8 years ago

I solve this by passing props to the Swiper component, and calling scrollTo in componentWillReceiveProps accordingly.

PimDeWitte commented 8 years ago

@drrazor can you share a code example?

luiscript commented 8 years ago

@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.

PimDeWitte commented 8 years ago

@luiscript thank you!

RonakKhandelwal commented 8 years ago

+1 We should have a prop like current page or something like that.

gastonf-dev commented 8 years ago

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)}

The0racle commented 8 years ago

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.

YannisDC commented 7 years ago

Can you also pass this ref to a child component? So they can have buttons that trigger the Swiper parent?

rahls7 commented 7 years ago

@YannisDC Did you figure out a way to pass it to the child component and scrolling accordingly?

zawars commented 7 years ago

Doesn't works with loadMinimal = true @gferreyra91

jkurei commented 6 years ago

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.

MewX commented 5 years ago

@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);
rptoma commented 4 years ago

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.

notmarinho commented 4 years ago

Using React Hooks, this code bellow worked for me:

const swiper = useRef(null)

<Swiper
            ref={swiper}
            {...OtherProps}>
</Swiper>

<Button onPress={() => swiper.current.scrollTo(1) }/>

ningacoding commented 4 years ago

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} />;
}
elganiesta commented 3 years ago

navigation={{ prevEl: '.classname-of-button-prev', nextEl: '.classname-of-button-next', }}