我正在尝试用firestore给数据分页(无限滚动我的tableview),我已经尽我所能的整合了google给的分页代码,但是我仍然不能正确的加载数据。
初始数据集根据需要加载到表视图中。然后,当用户点击屏幕底部时,下一个“x”数量的项被加载。但是当用户第二次点击屏幕底部时,相同的“x”项被简单地附加到表视图中。相同的项被无限期地添加。
所以它是最初的3个“骑”对象,然后是接下来的4个“骑”对象,永远重复。
123 4567 4567 4567 4567
如何正确加载数据?
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
if offsetY > contentHeight - scrollView.frame.height {
// Bottom of the screen is reached
if !fetchingMore {
beginBatchFetch()
}
}
}
func beginBatchFetch() {
// Array containing "Ride" objcets is "rides"
fetchingMore = true
// Database reference to "rides" collection
let ridesRef = db.collection("rides")
let first = ridesRef.limit(to: 3)
first.addSnapshotListener { (snapshot, err) in
if let snapshot = snapshot {
// Snapshot isn't nil
if self.rides.isEmpty {
// rides array is empty (initial data needs to be loaded in).
let initialRides = snapshot.documents.compactMap({Ride(dictionary: $0.data())})
self.rides.append(contentsOf: initialRides)
self.fetchingMore = false
DispatchQueue.main.asyncAfter(deadline: .now() + 5, execute: {
self.tableView.reloadData()
})
print("first rides loaded in")
}
} else {
// Error
print("Error retreiving rides: \(err.debugDescription)")
return
}
// reference to lastSnapshot
guard let lastSnapshot = snapshot!.documents.last else{
// The collection is empty
return
}
let next = ridesRef.limit(to: 4).start(afterDocument: lastSnapshot)
next.addSnapshotListener({ (snapshot, err) in
if let snapshot = snapshot {
if !self.rides.isEmpty {
let newRides = snapshot.documents.compactMap({Ride(dictionary: $0.data())})
self.rides.append(contentsOf: newRides)
self.fetchingMore = false
DispatchQueue.main.asyncAfter(deadline: .now() + 7, execute: {
self.tableView.reloadData()
})
print("new items")
return
}
} else {
print("Error retreiving rides: \(err.debugDescription)")
return
}
})
}
}
4条答案
按热度按时间e4yzc0pl1#
这就是我提出的解决方案!很可能这个解决方案会多次调用firestore,为任何真实的项目创建一个大的账单,但它可以作为一个概念的证明,我猜你会说。
如果您有任何建议或编辑,请随时分享!
qxgroojn2#
虽然有点晚了,但我还是想分享一下我是如何使用
query.start(afterDocument:)
方法来完成的。结果是这样的:
这是一个reference。
niknxzdl3#
我的解决方案类似于@yambo,但是,我尽量避免对数据库进行额外的调用。在第一次调用数据库后,我返回10个对象,当需要加载新页面时,我会保留一个关于对象数量的参考,并检查计数+ 9是否在新计数的范围内。
qjp7pelc4#
简单,快速和容易的方法是...
类馈送视图控制器:UI视图控制器、UI视图委托、UI视图数据源、馈送单元格委托{
}