首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >在SwiftUI中,控制事件在哪里,即用于检测列表数据底部的scrollViewDidScroll

在SwiftUI中,控制事件在哪里,即用于检测列表数据底部的scrollViewDidScroll
EN

Stack Overflow用户
提问于 2019-06-14 16:29:55
回答 6查看 13.6K关注 0票数 19

在SwiftUI中,是否有人知道当用户到达导致事件检索额外数据块的列表底部时要检测的控制事件(如scrollViewDidScroll )在哪里?还是有一种新的方法来做到这一点?

似乎UIRefreshControl()也不在那里..。

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2019-08-18 19:41:40

您可以检查最新的元素是否出现在onAppear中。

代码语言:javascript
复制
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
                    }
                }
            }
        }
    }
}
票数 13
EN

Stack Overflow用户

发布于 2019-06-14 17:28:18

SwiftUI -中缺少了很多特性,目前似乎不可能实现。

但这里有一个解决方案--

博士直接跳到答案的底部。

一个有趣的发现,同时对ScrollViewList做了一些比较

代码语言:javascript
复制
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也做了同样的尝试,行为也不一样。

代码语言:javascript
复制
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 { }中。

票数 27
EN

Stack Overflow用户

发布于 2019-11-15 11:14:53

如果您需要更精确的信息,说明如何滚动scrollView或列表,您可以使用以下扩展作为解决方法:

代码语言:javascript
复制
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
    }
}

您可以像这样利用更改后的框架:

代码语言:javascript
复制
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不可用的情况下,这会有所帮助。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56602089

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档