fermoya / SwiftUIPager

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

[FEAT] Pager automatic scroll #196

Closed SpectatorNan closed 3 years ago

SpectatorNan commented 3 years ago

Is your feature request related to a problem? Please describe.

i want the pager content automatic scroll, for example, fspagerview : pagerView.automaticSlidingInterval = 3.0 auto scroll every 3 seconds;

fermoya commented 3 years ago

I think this is easy enough to implement by using a Timer. It makes more sense to implement it on the client's side rather inside the library. Reason is Pager might be redrawn if there's a state change in the container's view. You'd need to something like this:

struct MyView: View {

  @StateObject var page: Page = .first()

  var body: some View {
    Pager(...)
      .disableDragging()
      .onAppear {
        Timer
          .publish(
            every: 3.0, // Use desired interval
            on: .main, 
            in: .default
          )
          .sink { _ in
            withAnimation { page.update(.next)) } // use desired animation and desired page increment
          }
      }
  }

}
fermoya commented 3 years ago

Confirmed, it's not reliable to have a Timer set inside Pager as the container view might redraw it and then the count is lost. Especially if you combine several Pager in the same screen, one will trigger an update of the other.

See Hacking with Swift for reference of how to use timers with Combine. Alternatively you can use the "old way":

https://user-images.githubusercontent.com/11335612/110016946-9018cc80-7d1d-11eb-8a1b-66ba6a586214.mov

SpectatorNan commented 3 years ago

yeah, I have tried to customize a simple pager and found that the redraw caused the timer to be created repeatedly. Causes the scrolling effect to fail.

I am trying and learning SwiftUI and Combine to write an APP, and there is a lot of thinking that has not been converted from UIKit. Thank you for your answer

SpectatorNan commented 3 years ago

I found that after the view toggles through the tabview, the scrolling is abnormal

By breakpoint discovery, the onReceive was received, but no scrolling animation was performed after the Page Update was executed

current version: 2.0.0

I will continue to try this

SpectatorNan commented 3 years ago

my view code:

Pager(page: page, data: Array(0..<selectModel.banners.count), id: \.self) { (idx) in
                            bannerView(banner: selectModel.banners[idx]).cornerRadius(3) // custom image view...
                        }
                        .allowsDragging()
                        .loopPages()
                        .pagingAnimation({ currentPage, nextPage, totalShift, velocity in
                                return PagingAnimation.custom(animation: .linear)
                            })
                        .onPageWillChange({ (newIdx) in
                            SNLog("will page - \(newIdx)")
                        })
                        .onPageChanged({ (newIndex) in
                                 // do something
                            SNLog("page - \(newIndex)")
                         })
                        .itemSpacing(10.fit)
                        .onReceive(timer) { _ in
                            withAnimation {
                                page.update(.next)
                            }
                        }.frame(height: bannerHeight)