leecade / react-native-swiper

The best Swiper component for React Native.
MIT License
10.37k stars 2.35k forks source link

Swiper does not start at initial index, unless I set loop to false #527

Closed thesubway closed 6 years ago

thesubway commented 6 years ago

Which OS ?

iOS

Version

Which versions are you using: React 16.0.0-alpha.12

Expected behaviour

Upon launch, start at the first page

Actual behaviour

Upon launch, starts at the last page

How to reproduce it>

export default class App extends Component { constructor(props) { super(props); this.state = { }; } render() { return (

) } } AppRegistry.registerComponent('AwesomeProject', () => App); ### Steps to reproduce 1.Create App Component using the above code 2.Add styles variable from the README 3.Do not set the loop property When I set Swiper loop={false}, there is no issue. In that case, it correctly starts at the initial page.
dwilt commented 6 years ago

@thesubway I ran into this too. This is indeed a bug. Do you have flex: 1 on the Swiper as a style? If so, try and remove it. That fixed it for me.

arribbar commented 6 years ago

Do you still have the bug @thesubway ? If yes, can you fork the project and reproduce the bug? I have not enough time to do it on my own. Thanks

thesubway commented 6 years ago

Here is an example of my issue, reproduced, where page 2 shows up first: https://github.com/thesubway/IssueTester

jketcham commented 6 years ago

I'm also experiencing a variant of this issue, except on initial render the index is fine but on subsequent renders, the last slide is shown even though the index is still 0. Setting loop to false fixes this, so I imagine there's something wrong with how offset is calculated in relation to looping.

arribbar commented 6 years ago

It looks like this is the same bug than #570. Can you try again with the last version released yesterday, 1.5.13. This PR https://github.com/leecade/react-native-swiper/pull/572 has been merged and should fixed this bug. If not, reopen this issue. Thanks!

bispul commented 6 years ago

its still not working on 1.5.13. does anyone have a fix ?

hugweb-zz commented 6 years ago

I don't know if it's exactly the same issue but when loop is set to TRUE and I reach the last slide : the old state is display (of the page) before displaying the current one which create a glitch.

I think the problem is located in the updateIndex method and more particularly in the setState method.

if (loopJump) {
      // when swiping to the beginning of a looping set for the third time,
      // the new offset will be the same as the last one set in state.
      // Setting the offset to the same thing will not do anything,
      // so we increment it by 1 then immediately set it to what it should be,
      // after render.
      if (offset[dir] === this.internals.offset[dir]) {
        newState.offset = { x: 0, y: 0 }
        newState.offset[dir] = offset[dir] + 1
        this.setState(newState, () => {                     <========== here
          this.setState({ offset: offset }, cb) 
        })
      } else {
        newState.offset = offset
        this.setState(newState, cb)
      }
    } else {
      this.setState(newState, cb)
    }

Here you can see what I mean. Changing something on the page scrolling left/right to come back and you see the glitch

Any ideas @leecade?

2014-10-22 11_35_09

dktan commented 6 years ago

init offset is set in onLayout function, and onLayout is not called when view update. So, your problem was content loaded after page rendered, and all you layout was still set up as you have no children. Quick work around: do not render swiper until all image loaded.

but still I think is fair to ask a swiper library to handle content update.

windydang26 commented 6 years ago

version 1.5.13 still not working. index changed to 0 but screen still is last screen.

kevinEsherick commented 6 years ago

@windydang26 Still not working for me either. I have just set loop to false, since looping isn't critical for me, and that fixes it, but it would be nice if we could find the solution. I believe it only happens upon touch events in which setState is called, as someone hinted to previously. If at index 0, when setState is called it remains at index 0 but displays the content of the final index. It also prevents you from swiping right (looping back to the final index) when this occurs. Then when you swipe left it returns to the proper display of the 0 index. Maybe that helps someone better understand the problem, not sure. But if looping isn't critical then turning it off is an easy fix

CallmeJay commented 5 years ago

still can't work.help me

joelbowen commented 5 years ago

I think this issue should be re-opened. I am experiencing a similar issue:

Setting loop to false resolves the issue, but certainly isn't ideal.

byunghyunpark commented 5 years ago

I have the same bug on 1.5.13 version

evanyz commented 5 years ago

same issue on 1.5.13 and 1.5.14

Lelelo1 commented 5 years ago

For me this issue occurs on second render. version 1.5.14. Doing something that triggers a render like pressing a button outside of this component makes it go from index 0 to last index.

pgonzalez-santiago commented 5 years ago

Same here

ekSec commented 4 years ago

Same Here

karmatobgyel commented 4 years ago

same here. on ios , it wont swipe left at the first swipe.

alikianinejad commented 4 years ago

same here

mattgilbertnet commented 3 years ago

same here

reflexator commented 3 years ago

Anyone find solution for this?

emp commented 1 year ago

on initialization, swiper.slideToLoop(0, 0) did it for me

React example, I want to only have a loop when I have more than one image:

useEffect(() => {
    if (swiperInstance && images.length > 1)
      swiperInstance.slideToLoop(0, 0)
  }, [images, swiperInstance]);
<Swiper loop={images.length > 1}>
alan-automationworks commented 1 year ago

on initialization, swiper.slideToLoop(0, 0) did it for me

React example, I want to only have a loop when I have more than one image:

useEffect(() => {
    if (swiperInstance && images.length > 1)
      swiperInstance.slideToLoop(0, 0)
  }, [images, swiperInstance]);
<Swiper loop={images.length > 1}>

This worked for me, @emp. Thank you. But I'm wondering, is it not a bad idea to pass a ref to an useEffect?