2016-08-01 50 views
1

我正在從Firebase數據庫加載數據。我正在嘗試在用戶滾動時加載數據。例如,如果他滾動了大約20 cells,那麼我想多加載一下大約5 cells。我想實現像這樣,但它不工作:在Swift Firebase中滾動時的分頁

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() 

       } 
      } 
     }) 
    } 
} 

這是我火力地堡結構:

enter image description here

有沒有更好的解決方案,還是應該繼續這樣嘗試?

Here你可以看到整個代碼。我知道它缺乏OO,但我正在學習:)

回答

2

您可能想要使用offset來在您的應用中實現分頁。

首先,在子路徑中添加order鍵,可能是當前插入的時間戳,以便您可以對其進行排序並在分頁中使用它。

例如,

"brands": { 
     "catch" : { 
      ... 
      ... 
      "pOrder" : 555 
     }, 
     "etan" : { 
      ... 
      ... 
      "pOrder" : 444 
     }, 
     "general" : { 
      ... 
      ... 
      "pOrder" : 555 
     }. 
     ..... 
     } 

現在,爲了實現分頁,你將檢索21條記錄,並在這些記錄中,第一個20將記錄在表格視圖中使用,而最後一條記錄將被用於檢索接下來的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) 
     }) 
    } 

而且從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() 
     } 
    } 

同樣當用戶滾動到下在table view,調用此方法,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的數組來實現它。所以當更新任何記錄時,retrievePost將被調用從offsetArray。在正常情況下(在檢索viewDidLoadscrollViewDidEndDragging的數據時),偏移量將爲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方法,並傳遞一個額外的參數來檢索特定數量的記錄。

+0

你是什麼意思kOffset和findOffsetFromArray。我必須創建另一個數組嗎? –

+0

@TarvoMäesepp我已經添加了更多關於'offsetAray'和'kOffset'的解釋。 – triandicAnt

+0

你的回答絕對好,我接受它,但我認爲我不會繼續。這太令人困惑:D沒有更簡單的方法來實現這一點嗎?有沒有任何工作的例子,你可能知道嗎? –