SwiftUIPager icon indicating copy to clipboard operation
SwiftUIPager copied to clipboard

[BUG] Standard animation not working while using Loop

Open ghost opened this issue 3 years ago • 4 comments

Describe the bug While using Loop the standard animation is not working properly. If I add a data from view its working fine but when i try to use data from viewmodel then its not woking properly

To Reproduce Add a data from ViewModel and add a loopPages()

  • Sample code
@ObservedObject var discoverVM: DiscoveryViewModel
var body: some View {
 Pager(page: .first(), data: discoverVM.showProfiles, id: \.self) {
                    self.pageView($0.connections ?? 0)
                }
                .pagingPriority(.simultaneous)
                .draggingAnimation(.standard)
                .loopPages()
                .sensitivity(.high)
                .itemSpacing(10)
                .itemAspectRatio(1.3, alignment: .start)
                .padding(20)
}

Expected behavior I want standard animation with using loopPages()

Screenshots / Videos If applicable, add screenshots to help explain your problem. https://user-images.githubusercontent.com/80446711/194536499-8c02f913-72f0-46f8-9832-8708cc212e45.MP4

Environment: Xcode : 14.1 iOS: 15.5

  • OSX: [iOS]
  • Device [iPhoneXs Max]
  • SwiftUIPager version [2.4.0]

Additional context Add any other context about the problem here.

ghost avatar Oct 07 '22 10:10 ghost

same problem

dmikots avatar Oct 28 '22 14:10 dmikots

Hi @smallworldpc , @dmikots

I fixed this issue by doing a small trick may helps someone later 😌✌🏼

The problem that the Pager needs at least 5 elements to work as expected (don't ask me why 👀)

My trick is to repeat data if it has count < 5:

        private func fixBanners(_ array: [YourModelItem]) -> [YourModelItem]{
        if array.count > 1 && array.count < 5 {
            let originalCount = array.count
            let expectedCount = 5
            let remaingCount = expectedCount - originalCount
            let targetCount = originalCount * ( remaingCount == 1 ? remaingCount + 1 : remaingCount )
            let repeatCount = max(1, targetCount / originalCount)
            
            var repeatedArray = Array(repeating: array, count: repeatCount).flatMap { $0 }
            let remainingCount = targetCount - repeatedArray.count
            
            if remainingCount > 0 {
                repeatedArray += array.prefix(remainingCount)
            }
            
            
/** Important for identifiable models: change object identifier **/
repeatedArray = repeatedArray.map { object in
                var newObj = object
                newObj.id = UUID()
                return newObj
            }
            return repeatedArray
        }else{
            return array
        }
    }

ikhaled-ali avatar Jun 11 '23 20:06 ikhaled-ali

@ikhaled-ali doesn't it work if you use loopPages(repeating: 2)?

fermoya avatar Jun 11 '23 21:06 fermoya

@ikhaled-ali doesn't it work if you use loopPages(repeating: 2)?

Unfortunately no 😞, the transition looks like the next page comes from behind the current one.

ikhaled-ali avatar Jun 11 '23 21:06 ikhaled-ali