我正在从 Firebase 数据库加载数据。我正在尝试在用户滚动时加载数据。例如,如果他滚动了大约 20 个 cells
,那么我想再加载大约 5 个 cells
。我正在尝试像这样实现它,但它不起作用:
func parseSnusBrands(){
let ref = FIRDatabase.database().reference().child("Snuses").child("Brands")
ref.queryOrderedByKey().queryLimitedToLast(20).observeEventType(.Value, withBlock: { (snapshot) in
if snapshot.exists() {
if let all = (snapshot.value?.allKeys)! as? [String]{
self.snusBrandsArray = all
self.snusBrandsTableView.reloadData()
}
}
})
}
并检测滚动了多少个单元格:
override func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) {
if indexPath.row == 20 {
let ref = FIRDatabase.database().reference().child("Snuses").child("Brands")
ref.queryOrderedByKey().queryLimitedToLast(20).observeEventType(.Value, withBlock: { (snapshot) in
if snapshot.exists() {
if let all = (snapshot.value?.allKeys)! as? [String]{
self.snusBrandsArray = all
self.snusBrandsTableView.reloadData()
}
}
})
}
}
这是我的 Firebase 结构:
是否有更好的解决方案或者我应该继续这样尝试?
Here你可以看到整个代码。我知道它缺少 OO 但我正在学习 :)
最佳答案
您可能希望使用 offset
在您的应用中实现分页。
首先,在您的子路径中添加一个 order
键,可能是插入的当前时间戳,以便您可以对其进行排序并在分页中使用它。
例如。
"brands": {
"catch" : {
...
...
"pOrder" : 555
},
"etan" : {
...
...
"pOrder" : 444
},
"general" : {
...
...
"pOrder" : 555
}.
.....
}
现在,要实现分页,您将检索 21 条记录,在这些记录中,前 20 条将是要在 TableView 中使用的记录,而最后一条记录将是将要使用的 偏移量
检索下一组记录。
创建一个从 firebase
获取数据的函数:
// MARK: Retrieving Data: Firebase
/*
retrieve current set of posts sorted by updated time of posts
*/
func retrievePost(offset: NSNumber, callFlag: Bool, completion: (result: AnyObject?, error: NSError?)->()){
// As this method is called from viewDidLoad and fetches 20 records at first.
// Later when user scrolls down to bottom, its called again
let postsRef = ref.child(kDBPostRef)
var startingValue:AnyObject?
// starting value will be nil when this method is called from viewDidLoad as the offset is not set
if callFlag{
if offset == 0{
startingValue = nil
}
else{
startingValue = offset
}
} else{
// get offset from the offsetArray
startingValue = self.findOffsetFromArray()
}
// sort records by pOrder fetch offset+1 records
self.refHandler = postsRef.queryOrderedByChild("pOrder").queryStartingAtValue(startingValue).queryLimitedToFirst(kPostLimit + 1).observeEventType(FIRDataEventType.Value, withBlock: { (snapshot) in
// flag is for setting the last record/ 21st as offset
var flag = 0
let tempPost = NSMutableSet()
// iterate over children and add to tempPost
for item in snapshot.children {
// check for offet, the last row(21st) is offset ; Do not add last element in the main table list
flag += 1
if flag == 21 && callFlag == true{
// this row is offset
self.kOffset = item.value?["pOrder"] as! NSNumber
self.offSetArray?.append(self.kOffset)
continue
}
// create Post object
let post = Post(snapshot: item as! FIRDataSnapshot)
// append to tempPost
tempPost.addObject(post)
}
// return to the closure
completion(result:tempPost, error:nil)
})
}
然后从 viewDidLoad
调用此 updateNewRecords
方法,传递 0
以检索前 20 条记录。
func updateNewRecords(offset:NSNumber, callFlag: Bool){
self.retrievePost(offset,callFlag:callFlag) { (result,error) -> Void in
// let tempArray = result as! [Post]
let oldSet = Set(self.posts)
var unionSet = oldSet.union(result as! Set<Post>)
unionSet = unionSet.union(unionSet)
self.posts = Array(unionSet)
self.postsCopy = self.posts
// print(self.posts.count)
self.posts.sortInPlace({ $0.pOrder> $1.pOrder})
self.reloadTableData()
}
}
再次当用户滚动到 TableView
底部时,调用此方法,updateNewRecords
传递偏移量,以检索下一组 20 条记录。
func scrollViewDidEndDragging(scrollView: UIScrollView, willDecelerate decelerate: Bool) {
// UITableView only moves in one direction, y axis
let currentOffset = scrollView.contentOffset.y
let maximumOffset = scrollView.contentSize.height - scrollView.frame.size.height
// Change 10.0 to adjust the distance from bottom
if maximumOffset - currentOffset <= 10.0 {
self.updateNewRecords(self.kOffset, callFlag:true)
}
}
当您的数据在 firebase
中被修改时,您可以维护一个数组 offsetArray
来更新表值。
例如假设一些数据在你的表中的某处被修改,在这种情况下 observeEventType
将被调用,你应该只从 firebase
中获取那些范围的记录。您可以通过维护一个 offsets
数组来实现它。因此,当任何记录更新时,将使用 offsetArray
中相应的 offset
调用 retrievePost
。在正常情况下,(从 viewDidLoad
和 scrollViewDidEndDragging
检索数据时),偏移量将为 kOffset
,在其余情况下(在收听时)数据更改),偏移量将来自 offsetArray
。
您可以定义一个函数,该函数将返回特定更新列的 offset
值:
// find the offset from the offsetDict
func findOffsetFromArray() -> NSNumber{
let idx = self.kClickedRow/20 // kClickedRow is the updated row in the table view
return self.offSetArray![idx]
}
您还可以修改retrievePost
方法并传递一个额外的参数来检索一定数量的记录。
关于json - 在 Swift Firebase 中滚动时分页,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38705925/