2016-08-01 4 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() 

       } 
      } 
     }) 
    } 
} 

Это мой Firebase структура:

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

И называют этот метод updateNewRecords из viewDidLoad, проходя 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) 
     } 
    } 

Вы можете сохранить массив offsetArray для обновления таблицы значений, когда ваши данные изменены в firebase.

См., Например, предположим, что некоторые данные будут изменены где-то в вашей таблице, в этом случае будет вызываться observeEventType, и вы должны выбрать только этот диапазон записей от firebase. Вы можете достичь этого, поддерживая массив offsets. Поэтому, когда какая-либо запись обновляется, retrievePost будет вызываться с соответствующим offset от offsetArray. В нормальном случае (при извлечении данных из 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 метод и передать дополнительный параметр, чтобы получить определенное количество записей.

+0

Что вы подразумеваете под kOffset и findOffsetFromArray. Нужно ли создавать другой массив? –

+0

@ TarvoMäesepp Я добавил больше объяснений о 'offsetAray' и' kOffset'. – triandicAnt

+0

Ваш ответ абсолютно хороший, и я принимаю его, но я думаю, что я не пойду дальше. Это слишком запутанно: D Нет ли более простого способа достичь этого? Есть ли какой-нибудь рабочий пример, может быть, вы знаете? –