我正在尝试使用Firestore对数据进行分页(无限滚动我的表 View )。我已经尽我所能集成了google给出的用于分页的代码,但是仍然无法正确加载数据。
初始数据集将根据需要加载到表 View 中。然后,当用户点击屏幕底部时,将加载下一个“x”项。但是,当用户第二次点击屏幕底部时,将相同的“x”项简单地附加到表中 View 。相同的项目会无限期地添加。
因此,其最初的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
}
})
}
}
最佳答案
所以这是我想出的解决方案!这个解决方案很可能会多次调用firestore,从而为任何实际项目产生大量账单,但是我想您可以说它可以作为概念证明。
如果您有任何建议或正在编辑,请随时与分享!
这是所有变量的初始化方式:
var rides = [Ride]()
var lastDocumentSnapshot: DocumentSnapshot!
var fetchingMore = false
如果您有任何建议或修改,请随时分享!
func scrollViewDidScroll(_ scrollView: UIScrollView) {
let offsetY = scrollView.contentOffset.y
let contentHeight = scrollView.contentSize.height
//print("offsetY: \(offsetY) | contHeight-scrollViewHeight: \(contentHeight-scrollView.frame.height)")
if offsetY > contentHeight - scrollView.frame.height - 50 {
// Bottom of the screen is reached
if !fetchingMore {
paginateData()
}
}
}
// Paginates data
func paginateData() {
fetchingMore = true
var query: Query!
if rides.isEmpty {
query = db.collection("rides").order(by: "price").limit(to: 6)
print("First 6 rides loaded")
} else {
query = db.collection("rides").order(by: "price").start(afterDocument: lastDocumentSnapshot).limit(to: 4)
print("Next 4 rides loaded")
}
query.getDocuments { (snapshot, err) in
if let err = err {
print("\(err.localizedDescription)")
} else if snapshot!.isEmpty {
self.fetchingMore = false
return
} else {
let newRides = snapshot!.documents.compactMap({Ride(dictionary: $0.data())})
self.rides.append(contentsOf: newRides)
//
DispatchQueue.main.asyncAfter(deadline: .now() + 1, execute: {
self.tableView.reloadData()
self.fetchingMore = false
})
self.lastDocumentSnapshot = snapshot!.documents.last
}
}
}
关于swift - 使用Firebase Firestore分页-Swift 4,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/52192062/