I have written a generic ViewPager with TabView and it works perfectly. However, I want to pause the timer (auto swipe) when user starts dragging and resume it when user finishes the dragging. Is there anyway to do that?
This is my ViewPager:
struct ViewPager<Data, Content> : View
where Data : RandomAccessCollection, Data.Element : Identifiable, Content : View {
private var timer = Timer.publish(every: 2, on: .main, in: .common).autoconnect()
@Binding var currentIndex: Int
private let data: [Data.Element]
private let content: (Data.Element) -> Content
private let isTimerEnabled: Bool
private let showIndicator: PageTabViewStyle.IndexDisplayMode
init(_ data: Data,
currentIndex: Binding<Int>,
isTimerEnabled: Bool = false,
showIndicator: PageTabViewStyle.IndexDisplayMode = .never,
@ViewBuilder content: @escaping (Data.Element) -> Content) {
_currentIndex = currentIndex
self.data = data.map { $0 }
self.content = content
self.isTimerEnabled = isTimerEnabled
self.showIndicator = showIndicator
}
private var totalCount: Int {
data.count
}
var body: some View {
TabView(selection: $currentIndex) {
ForEach(data) { item in
self.content(item)
.tag(item.id)
}
}.tabViewStyle(PageTabViewStyle(indexDisplayMode: showIndicator))
.onReceive(timer) { _ in
if !isTimerEnabled {
timer.upstream.connect().cancel()
} else {
withAnimation {
currentIndex = currentIndex < (totalCount - 1) ? currentIndex + 1 : 0
}
}
}
}
}