2017-06-19 56 views
1

請幫我看看我的錯誤是什麼。我有一個表視圖,數據源是一個名爲items的數組。從items數組中刪除一個項目後,調用cellForRowAt方法,參數indexPath.row與items.count相等。這種情況只發生在行數足以讓一個項目不在表格視圖的視圖中時。 當它發生時,它會導致致命錯誤(索引超出範圍)。在這種情況下使用hack,並且IndexPath.row的值會減少。從UITableView刪除項目後指數超出範圍

請看下面的圖片:

enter image description here

爲cellForRowAt下面的代碼:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
{ 
    let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell 

    var i = indexPath.row 
    if i >= items.count { i = items.count - 1 } //XXX: hack! Sometimes called with indexPath.row is equal with items.count :(
    cell.set(items[i]) 

    return cell 
} 

而對於刪除以下代碼:

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
{ 
    if (editingStyle == UITableViewCellEditingStyle.delete) 
    { 
     items.remove(at: indexPath.row) 

     tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade) 
    } 
} 

我想是不相關的,但我是我們ING iOS的11.0

UPDATE

我試過了,下面的非常簡單的代碼也受到了影響:

class ViewController: UIViewController, UITableViewDataSource, UITableViewDelegate 
{ 
    var items = ["0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F","G","H","I","J","K","L","M","N","O","P","Q","R","S","T","U","V","W","X","Y","Z"] 

    override func viewDidLoad() 
    { 
     super.viewDidLoad() 
    } 

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int 
    { 
     return items.count 
    } 

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell 
    { 
     let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) 
     cell.textLabel?.text = "\(items[indexPath.row])" 

     return cell 
    } 

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) 
    { 
     if (editingStyle == UITableViewCellEditingStyle.delete) 
     { 
      items.remove(at: indexPath.row) 
      tableView.deleteRows(at: [indexPath], with: UITableViewRowAnimation.fade) 
     } 
    } 
} 

如何重現:

  1. 滾動向下爲Y成爲屏幕上的最後一項

enter image description here

  • 嘗試刪除ý滑動到左側
  • enter image description here

  • 並獲得以下錯誤
  • enter image description here

    enter image description here

    +0

    「cellForRowAt」中的「hack」不應該在那裏。如果你確實需要它,那麼你在'numberOfRowsInSection'中有一個問題。 – rmaddy

    +0

    我的numberOfRowsInSection返回:return items.count –

    +0

    嘗試重新加載您的tableVew'tableView.reloadData()'後刪除該行(item作爲item中的索引),以便numberOfRowsInSection從新items.count更新 –

    回答

    3

    您的刪除代碼看起來不錯,但是您不應該在您的cellForRowAt中執行您的操作。像這樣做,而不是:

    func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell { 
        let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell 
        cell.set(items[indexPath.row]) 
    
        return cell 
    } 
    

    和你numberOfRowsInSection應該是這樣的:

    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int { 
        return items.count 
    } 
    

    更新:
    我們剛剛證實,這是關係到Xcode的9測試版和iOS版11中的錯誤。在Xcode 8.x上運行良好。 OP會就此向蘋果公司提交bug

    +0

    我的numberOfRowsInSection和你提到的一樣,這就是爲什麼我不明白是什麼問題,沒有其他線程,所以items數組不能被其他線程修改。 –

    +0

    @EdmundElmer,if你這樣做,因爲我在我的答案中,它仍然無法正常工作,那麼你的代碼中有其他的東西不能正常工作,爲問題添加更多的代碼,以便我們繼續調查 –

    +0

    謝謝, m會去掉所有不必要的,而不是問題相關的代碼,我會發布整個控制器代碼。再次感謝您的幫助! –