在Swift Firebase中滚动时的分页

时间:2016-08-01 18:42:36

标签: json swift uitableview firebase firebase-realtime-database

我正在从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 结构:

enter image description here

是否有更好的解决方案,还是应该继续这样做?

Here您可以看到整个代码。我知道它缺少OO,但我正在学习:)。

1 个答案:

答案 0 :(得分:2)

您可能希望使用 get-service $myVariable* | where-object {($_.status -eq "stopped")} 在您的应用中实现分页。

首先,在您的子路径中添加一个offset键,可能是插入的当前时间戳,以便您可以订购它并在分页中使用它。

例如。

order

现在,要实现分页,您将检索21条记录,在这些记录中,前20条记录将在表格视图中使用,而最后一条记录将是"brands": { "catch" : { ... ... "pOrder" : 555 }, "etan" : { ... ... "pOrder" : 444 }, "general" : { ... ... "pOrder" : 555 }. ..... } ,将用于检索下一条记录记录集。

创建一个从offset获取数据的函数:

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) }) } 调用此updateNewRecords方法,传递viewDidLoad以检索前20条记录。

0

再次当用户在 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() } } 中滚动到底部时,调用此方法,table view传递偏移量,以检索下一组20条记录。

updateNewRecords

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) } } 中修改数据时,您可以维护数组offsetArray以更新表值。

例如假设某些数据在表格的某处被修改,在这种情况下,firebase将被调用,您应该只从observeEventType获取那些记录范围。您可以使用维护firebase数组来实现它。因此,当更新任何记录时,将使用offsets中的相应retrievePost来调用offset。在正常情况下(从offsetArrayviewDidLoad检索数据时),偏移量将为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] } 方法并传递额外参数以检索一定数量的记录。