2016-04-07 2 views
1

Я пытаюсь динамически добавлять строки в нижней части моего представления таблицы, в то время как пользователь прокручивается. Идея состоит в том, что пользователь этого не замечает и может прокручивать «бесконечно».App crashes после insertRowsAtIndexPaths

Когда пользователь достигает нижних 40 ячеек таблицы, я хотел бы нанести 100 новых ячеек на дно.

Теперь, когда я звоню

 tableView.beginUpdates() 
     tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .None) 
     tableView.endUpdates() 

приложение кажется аварии на tableView.endUpdates():

Terminating app due to uncaught exception 'NSRangeException', reason: '*** -[__NSArrayM objectAtIndex:]: index 10 beyond bounds [0 .. 9]'

Я твердо верю, что мой DataProvider для UITableView правильно обновляется, прежде чем я выполнить обновление. Я не знаю, почему он рушится.

Я сделал очень простую реализацию для этой цели. Кто-нибудь понимает, почему нижеследующее разрушится?

private let CellTreshold: Int = 100 
var cellCount: Int = 100 

@IBOutlet weak var tableView: UITableView! 

// UITableViewDataSource 
func numberOfSectionsInTableView(tableView: UITableView) -> Int { 
    return 1 
} 

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
    return cellCount 
} 

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell { 
    let cell = tableView.dequeueReusableCellWithIdentifier("MyCellIdentifier") as! UITableViewCell 
    cell.index = indexPath.row 

    return cell 
} 

func tableView(tableView: UITableView, willDisplayCell cell: UITableViewCell, forRowAtIndexPath indexPath: NSIndexPath) { 

    if indexPath.row == cellCount - 40 { 
     print("indexPath = \(indexPath.row); inserting \(CellTreshold) cells") 
     var indexPaths = [NSIndexPath]() 

     let beginIndex = cellCount 
     let endIndex = cellCount + CellTreshold 
     for i in beginIndex ..< endIndex { 
      indexPaths.append(NSIndexPath(forRow: i, inSection: 0)) 
     } 
     cellCount += CellTreshold 

     tableView.beginUpdates() 
     tableView.insertRowsAtIndexPaths(indexPaths, withRowAnimation: .None) 
     tableView.endUpdates() 
    } 
} 
+1

Try с 'пусть beginIndex = cellCount - 1'? Может быть, вы вставляете после последнего – zcui93

+0

Я думаю, что это была идея вставить новые ячейки после последнего. Проблема заключается в том, что вставка реализована в методе, который предназначен для использования для изменения отдельной ячейки, к которой он относится, на этом этапе не гарантируется, что весь вид таблицы правильно настроен и подготовлен для ввода новых строк и поэтому такая операция небезопасна, даже если она работает или используется для работы. –

+0

Возможно, стоит попробовать отладить и выяснить, что такое '[0 .. 9]' – zcui93

ответ

0

У меня была такая же проблема - она ​​рушилась, потому что код был в willDisplayCell. Благодаря @ A-жить для комментария

После того как я переехал мой код в scrollViewDidScroll его работает нормально, что-то вроде этого:

func scrollViewDidScroll(_ scrollView: UIScrollView) { 
    let offsetY = scrollView.contentOffset.y 
    let contentHeght = scrollView.contentSize.height 
    let scrollViewHeight = scrollView.frame.size.height 

    if (contentHeght - offsetY) < 3*scrollViewHeight { 
     //we are less than 3 page screens from the bottom 

     let rowNumbers = self.dataModel.getVisibleCells() 
     let newRowNumbers = self.dataModel.getMoreCells() 
     let newCells = newRowNumbers - rowNumbers 

     if newCells > 0 { 
      debugPrint("ae.ui adding cells \(newCells)") 

      let rowInd = rowNumbers - 1 
      var indexPaths = [IndexPath]() 
      for i in 1...newCells { 
       indexPaths.append(IndexPath(row: rowInd+i, section: 0)) 
      } 

      self.beginUpdates() 
      self.insertRows(at: indexPaths, with: .none) 
      self.endUpdates() 
     } 
    } 
}