我已经将 ScrollView 与 HStack 一起使用,现在我需要在用户最后达到滚动时加载更多数据。
var items: [Landmark]
我已经使用了我正在使用
HStack
在
ForEach
中添加的项目数组
ScrollView(showsHorizontalIndicator: false) {
HStack(alignment: .top, spacing: 0) {
ForEach(self.items) { landmark in
CategoryItem(landmark: landmark)
}
}
}
在 SwiftUI 中管理更多负载的最佳解决方案是什么,而不使用像 loadmore 按钮这样的自定义操作。
最好使用 ForEach 和 List 来实现此目的
struct ContentView : View {
@State var textfieldText: String = "String "
private let chunkSize = 10
@State var range: Range<Int> = 0..<1
var body: some View {
List {
ForEach(range) { number in
Text("\(self.textfieldText) \(number)")
}
Button(action: loadMore) {
Text("Load more")
}
}
}
func loadMore() {
print("Load more...")
self.range = 0..<self.range.upperBound + self.chunkSize
}
}
在此示例中,每次您按更多加载键,都会增加 State 属性的范围。您可以对 BindableObject 执行相同的操作。 如果您想自动执行此操作,可能您应该阅读有关 PullDownButton 的内容(我不确定它是否适用于 PullUp)
更新: 作为一个选项,您可以通过在最后一个单元格上使用 onAppear 修饰符来下载新项目(在本例中它是一个静态按钮)
var body: some View {
List {
ForEach(range) { number in
Text("\(self.textfieldText) \(number)")
}
Button(action: loadMore) {
Text("")
}
.onAppear {
DispatchQueue.global(qos: .background).asyncAfter(deadline: DispatchTime(uptimeNanoseconds: 10)) {
self.loadMore()
}
}
}
}
请记住,该调度是必要的,因为如果没有它,您将收到错误消息“在更新表视图时更新表视图”。您可能可以使用另一种异步方式来更新数据
如果您想继续使用带有
Data
而不是 Range
的 List,您可以实现下一个脚本:
struct ContentView: View {
@State var items: [Landmark]
var body: some View {
List {
ForEach(self.items) { landmark in
CategoryItem(landmark: landmark)
.onAppear {
checkForMore(landmark)
}
}
}
}
func checkForMore(_ item: LandMark) {
guard let item = item else { return }
let thresholdIndex = items.index(items.endIndex, offsetBy: -5)
if items.firstIndex(where: { $0.id == item.id }) == thresholdIndex {
// function to request more data
getMoreLandMarks()
}
}
}
您应该在 ViewModel 中工作并将逻辑与 UI 分开。
感谢 Donny Wals:完整示例