我该如何处理 swiftUI 中的scrollViewDidEndDecelerating 和scrollViewDidEndDragging 函数
我想设置scrollView的位置,使得scrollView停止移动时selectedIndex位于中间。
struct ContentView: View {
@State private var imageList: [String] = ["Onur","Onur","Onur","Onur","Onur","Onur","Onur","Onur","Onur"]
private var spacing: CGFloat = UIScreen.main.bounds.width / 2 - 100
@State private var moffsetX: CGFloat = 0
@State private var oldFffsetX: CGFloat = 0
@State private var isScrolling: Bool = false
@State private var selectedIndex: Int = 0
func horizontalScrollView() -> some View {
ScrollView(.horizontal){
Spacer()
HStack(spacing: spacing){
Spacer()
.frame(width: 50)
ForEach(imageList, id:\.self){ image in
Image(image)
.resizable()
.aspectRatio(contentMode: .fit)
.frame(width: 100,height: 100)
.clipShape(Circle())
.overlay(Circle().stroke(.blue,lineWidth: 4))
}
Spacer()
.frame(width: 50)
}
.overlay(GeometryReader{ geometry in
Color.clear.onChange(of: geometry.frame(in: .global).minX) { value, newValue in
oldFffsetX = value
moffsetX = newValue
let index = Int(round(geometry.frame(in: .global).minX / (-1 * (100 + spacing))))
if index != selectedIndex{
if index < 0{
selectedIndex = 0
} else if index > imageList.count - 1{
selectedIndex = imageList.count - 1
} else{
selectedIndex = index
}
}
isScrolling = true
}
})
Spacer()
}
}
}
您可以考虑使用 CurrentValueSubject 和 AnyPublisher 来检测滚动事件。这是用例的演示,
struct ScrollDetectorView: View {
let scrollSubject: CurrentValueSubject<CGFloat, Never>
let publisher: AnyPublisher<CGFloat, Never>
init() {
let scrollSubject = CurrentValueSubject<CGFloat, Never>(0)
self.publisher = scrollSubject
.debounce(for: .seconds(0.3), scheduler: DispatchQueue.main)
.dropFirst()
.eraseToAnyPublisher()
self.scrollSubject = scrollSubject
}
var body: some View {
ScrollView {
VStack(spacing: 5) {
ForEach(0...200, id: \.self) { i in
Text("\(i)")
.frame(width: 200, height: 100)
.background(Color.green)
}
}
.onPreferenceChange(ViewOffsetKey.self) { scrollSubject.send($0) }
}.coordinateSpace(name: "scroll")
.onReceive(publisher) {
print("Scroll did end: \($0)")
}
}
}
struct ViewOffsetKey: PreferenceKey {
typealias Value = CGFloat
static var defaultValue = CGFloat.zero
static func reduce(value: inout Value, nextValue: () -> Value) {
value += nextValue()
}
}