在SwiftUI中,是否有人知道当用户到达导致事件检索额外数据块的列表底部时要检测的控制事件(如scrollViewDidScroll )在哪里?还是有一种新的方法来做到这一点?
似乎UIRefreshControl()也不在那里..。
发布于 2019-08-18 19:41:40
您可以检查最新的元素是否出现在onAppear中。
struct ContentView: View {
@State var items = Array(1...30)
var body: some View {
List {
ForEach(items, id: \.self) { item in
Text("\(item)")
.onAppear {
if let last == self.items.last {
print("last item")
self.items += last+1...last+30
}
}
}
}
}
}发布于 2019-06-14 17:28:18
SwiftUI -中缺少了很多特性,目前似乎不可能实现。
但这里有一个解决方案--。
博士直接跳到答案的底部。
一个有趣的发现,同时对ScrollView和List做了一些比较
struct ContentView: View {
var body: some View {
ScrollView {
ForEach(1...100) { item in
Text("\(item)")
}
Rectangle()
.onAppear { print("Reached end of scroll view") }
}
}
}我在一个Rectangle中的100个Text项的末尾附加了一个print,并在onDidAppear中添加了一个print。
当ScrollView出现时,它就会启动,即使它显示了前20项。
滚动视图中的所有视图都会立即呈现,即使它们是屏幕外的。
我对List也做了同样的尝试,行为也不一样。
struct ContentView: View {
var body: some View {
List {
ForEach(1...100) { item in
Text("\(item)")
}
Rectangle()
.onAppear { print("Reached end of scroll view") }
}
}
}只有在到达print底部时才执行List!
因此,这是一个临时解决方案,直到 API得到更好的为止。
使用
List并在其末尾放置一个“假”视图,并将获取逻辑放入onAppear { }中。
发布于 2019-11-15 11:14:53
如果您需要更精确的信息,说明如何滚动scrollView或列表,您可以使用以下扩展作为解决方法:
extension View {
func onFrameChange(_ frameHandler: @escaping (CGRect)->(),
enabled isEnabled: Bool = true) -> some View {
guard isEnabled else { return AnyView(self) }
return AnyView(self.background(GeometryReader { (geometry: GeometryProxy) in
Color.clear.beforeReturn {
frameHandler(geometry.frame(in: .global))
}
}))
}
private func beforeReturn(_ onBeforeReturn: ()->()) -> Self {
onBeforeReturn()
return self
}
}您可以像这样利用更改后的框架:
struct ContentView: View {
var body: some View {
ScrollView {
ForEach(0..<100) { number in
Text("\(number)").onFrameChange({ (frame) in
print("Origin is now \(frame.origin)")
}, enabled: number == 0)
}
}
}
}滚动时将调用onFrameChange闭包。使用与透明不同的颜色可能会带来更好的性能。
编辑:通过在beforeReturn闭包之外获取框架,我对代码做了一些改进。在该闭包中geometryProxy不可用的情况下,这会有所帮助。
https://stackoverflow.com/questions/56602089
复制相似问题