Issue #812
Use GeometryReader to set width and a DragGesture on LazyVStack
CarouselView(
pageCount: images.count,
currentIndex: $selectedImageIndex
) {
ForEach(0 ..< images) { image in
// AsyncImage
}
}
struct CarouselView<Content: View>: View {
let pageCount: Int
@Binding var currentIndex: Int
@ViewBuilder let content: Content
@GestureState private var translation: CGFloat = 0
var body: some View {
GeometryReader { geometry in
LazyHStack(spacing: 0) {
self.content.frame(width: geometry.size.width)
}
.frame(width: geometry.size.width, alignment: .leading)
.offset(x: -CGFloat(self.currentIndex) * geometry.size.width)
.offset(x: self.translation)
.animation(.interactiveSpring(), value: currentIndex)
.animation(.interactiveSpring(), value: translation)
.gesture(
DragGesture()
.updating(self.$translation) { value, state, _ in
state = value.translation.width
}.onEnded { value in
let offset = value.translation.width / geometry.size.width
let newIndex = (CGFloat(self.currentIndex) - offset).rounded()
self.currentIndex = min(max(Int(newIndex), 0), self.pageCount - 1)
}
)
}
}
}
Read more
- Use DragGesture on HStack https://swiftwithmajid.com/2019/12/25/building-pager-view-in-swiftui/
- Use UIPageViewController under the hood https://github.com/nachonavarro/Pages/blob/master/Sources/Pages/PageViewController.swift
- Use PageTabViewStyle but need to cancel vertical scroll https://www.hackingwithswift.com/quick-start/swiftui/how-to-create-scrolling-pages-of-content-using-tabviewstyle