SwiftUI-检测ScrollView何时完成滚动? [英] SwiftUI - Detect when ScrollView has finished scrolling?
本文介绍了SwiftUI-检测ScrollView何时完成滚动?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!
问题描述
我需要找出我的 ScrollView
停止移动的确切时间.SwiftUI有可能吗?
import合并struct ContentView:查看{让检测器:CurrentValueSubject< CGFloat,Never>.让发布者:AnyPublisher< CGFloat,Never>在里面() {让检测器= CurrentValueSubject< CGFloat,从不>(0)self.publisher =检测器.debounce(for:.seconds(0.2),Scheduler:DispatchQueue.main).dropFirst().eraseToAnyPublisher()self.detector =检测器}var body:some View {ScrollView {VStack(间距:20){ForEach(0 ... 100,id:\ .self){我在长方形().frame(宽度:200,高度:100).foregroundColor(.green).overlay(Text("\(i)"))}}.frame(maxWidth:.infinity).background(GeometryReader {Color.clear.preference(key:ViewOffsetKey.self,值:-$ 0.frame(in:.named("scroll")).origin.y)}).onPreferenceChange(ViewOffsetKey.self){detector.send($ 0)}} .coordinateSpace(名称:滚动").onReceive(发布商){print(停止于:\($ 0)")}}}
I need to find out the exact moment when my ScrollView
stops moving.
Is that possible with SwiftUI?
Here would be an equivalent for UIScrollView
.
I have no idea after thinking a lot about it...
A sample project to test things out:
struct ContentView: View {
var body: some View {
ScrollView {
VStack(spacing: 20) {
ForEach(0...100, id: \.self) { i in
Rectangle()
.frame(width: 200, height: 100)
.foregroundColor(.green)
.overlay(Text("\(i)"))
}
}
.frame(maxWidth: .infinity)
}
}
}
Thanks!
解决方案
Here is a demo of possible approach - use publisher with changed scrolled content coordinates with debounce, so event reported only after coordinates stopped changing.
Tested with Xcode 12.1 / iOS 14.1
Note: you can play with debounce period to tune it for your needs.
import Combine
struct ContentView: View {
let detector: CurrentValueSubject<CGFloat, Never>
let publisher: AnyPublisher<CGFloat, Never>
init() {
let detector = CurrentValueSubject<CGFloat, Never>(0)
self.publisher = detector
.debounce(for: .seconds(0.2), scheduler: DispatchQueue.main)
.dropFirst()
.eraseToAnyPublisher()
self.detector = detector
}
var body: some View {
ScrollView {
VStack(spacing: 20) {
ForEach(0...100, id: \.self) { i in
Rectangle()
.frame(width: 200, height: 100)
.foregroundColor(.green)
.overlay(Text("\(i)"))
}
}
.frame(maxWidth: .infinity)
.background(GeometryReader {
Color.clear.preference(key: ViewOffsetKey.self,
value: -$0.frame(in: .named("scroll")).origin.y)
})
.onPreferenceChange(ViewOffsetKey.self) { detector.send($0) }
}.coordinateSpace(name: "scroll")
.onReceive(publisher) {
print("Stopped on: \($0)")
}
}
}
这篇关于SwiftUI-检测ScrollView何时完成滚动?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!
查看全文