fermoya / SwiftUIPager

Native Pager in SwiftUI
MIT License
1.3k stars 172 forks source link

[BUG] loopPages fades out on fast swipe #233

Closed Exocomp closed 2 years ago

Exocomp commented 3 years ago

Describe the bug Swiping fast (forward direction) with loopPages results in content completely fading out with no way to recover.

To Reproduce

Expected behavior When swiping fast (forward direction) with the loopPages option the content fading out with no way to recover.

Screenshots / Videos See attached video.

Environment:

https://user-images.githubusercontent.com/25571083/131396830-a137104a-8c71-4e83-af33-6cbf54d499c4.mov

Additional context n/a.

fermoya commented 3 years ago

Hi @Exocomp , thanks for your feedback. How many elements you have? It varies depending on the device, the issue you mention is known and there’s currently no fix for that.

If you notice the docs for that modifier:

To have a nice experience, ensure that the data passed in the intializer has enough elements to fill pages on both the screen and the sides. If your sequence is not large enough, use count to repeat it and pass more elements.

The workaround would be to use .loopPages(repeating: 2) or higher.

Exocomp commented 3 years ago

Hi @fermoya ,

It's with 10 items but I also I tested with higher like 100 with the same result.

var items = Array(0..<100)

I also tried:

.loopPages(repeating: 2)

It still has the same exact problem. Swiping fast just wants to fade out.

Any other ideas?

If I remove . loopPages then the issue doesn't occur.

fermoya commented 3 years ago

@Exocomp unfortunately I don't there's any other workaround. loopPages simply doesn't work well with multiplePagination

There's no fix for now, unfortunately. The issue here is that when Pager is looping the elements get reordered. When the scroll is slow, those elements that get off screen on one side won't appear on the other side but if you scroll fast enough that produces a weird effect where you see the elements moving sideways. The workaround for that is here. The logic around isEdgePage is prone to errors if the scroll of fast enough, that's why the elements disappear.

The fix for this would be either to improve that method or find a better workaround for that...

paulfreeman commented 3 years ago

I was confused by your comment that this is related to multiple pagination as I'm seeing it with the single pagination in your sample app as that is triggering with the source at line 164 in PagerContent.

Am I right to think that the if case here is solely for the multiplepagination case? In that case the following seems to work, at least for singlePagination, while the issues would remain as you say for the multiple case.

Group {                      
         if self.allowsMultiplePagination &&
            self.isInifinitePager && 
            self.isEdgePage(item) {
              EmptyView()
          } 
         else {
                 self.content(item.element)
          }
}
fermoya commented 3 years ago

@paulfreeman yes, apologies. For some reason I thought this was referring to multiplePagination. I'll add that extra check, this is just a problem when multiplePagination is enabled

fermoya commented 3 years ago

I take it back, that's actually a problem with or without multiplePagination. I'll need to revisit the algorithm

darecki commented 2 years ago

@fermoya do you know why it works flawlessly when scrolling left? This issue occurs only when scrolling right. It's interesting...

fermoya commented 2 years ago

It's probably something to do with the current implementation. It's not the best work I've done, I'll tell you that. I need to review it but that takes time.

Problem is elements get rearranged because the elements displayed change the order. So for instance, if you're showing 1 2 3 after swiping you should va e 3 2 1. In that transition, the element at the very left moves to the right in a weird effect, that's why I hide it. But perhaps there's a better solution, perhaps there's a better way for ForEach to handle this or it shouldn't be displayed in the first place.

Going in one direction or another night influence in that the implementation might be more permissive in one direction or because of the way the elements are arranged. Say the number of elements is even, it might be the case that there are more elements loaded in one side or the other

fermoya commented 2 years ago

this should be fixed here: https://github.com/fermoya/SwiftUIPager/releases/tag/2.3.3-beta.3

darecki commented 2 years ago

I can confirm the issue is fixed! Thanks for that :)