尝试在tableView中插入行时出现NSInternalInconsistencyException

时间:2017-05-04 20:42:51

标签: ios uitableview

我的应用程序中有一份食物日记应该可以插入一行,其中包含用户输入食物的信息。每次我尝试时都会收到此错误:“'NSInternalInconsistencyException',原因:'尝试将第3行插入第0部分,但更新后第0部分只有2行'”

这是执行插入的ViewController代码。

class FoodDiary: UITableViewController, AddRowDelegate {


var tableData = [[String: Any]]() //Datasource

    func didAddRow(name: String, calories: String, section: Int) {

    let getName = ["name":name, "calories":calories] as [String: Any]
    tableData.append(getName)
   let indexPath = IndexPath(row: tableData.count + 1, section: section)
    tableView.insertRows(at: [indexPath], with: .automatic)


    calsforToday.text = calories


    tableView.reloadData()
}

这是我的另一个ViewController,它显示用户何时使用协议方法输入数据。

    protocol AddRowDelegate {
func didAddRow(name : String, calories : String, section : Int)
 }




 class PopupVC: UIViewController {

var delegate: AddRowDelegate?
var section: Int?

@IBOutlet weak var foodTimeLabel: UILabel!
@IBOutlet weak var foodPopup2: UIView!
@IBOutlet weak var foodPopUp: UIView!
@IBOutlet weak var inputFood: UITextField!
@IBOutlet weak var inputCals: UITextField!

@IBAction func saveToDiary(_ sender: Any) {


    delegate?.didAddRow(name: inputFood.text!, calories: inputCals.text!, section: section!)


    dismiss(animated: true, completion: nil)


}
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {

if segue.identifier == "diaryEntry" {
        if let selectedIndexPath = 
  tableView.indexPathForSelectedRow?.first{
        let popVC = segue.destination as! PopupVC
            popVC.delegate = self


            if selectedIndexPath == 0 {
                let label = "Add Breakfast"
                popVC.foodLabel = label
                popVC.section = 0

两个VC的照片。

FoodDiary

PopUpVC

如何使用用户输入的信息插入行?

1 个答案:

答案 0 :(得分:1)

正如Dan在评论中所说,您的新索引路径行需要tableData.count - 1

例如,如果数组中有两个元素(count = 2),那么你有0行和1行(即count-1是最后一行)。

func didAddRow(name: String, calories: String, section: Int) {

    let getName = ["name":name, "calories":calories] as [String: Any]
    tableData.append(getName)
    let indexPath = IndexPath(row: tableData.count-1, section: section)
    tableView.insertRows(at: [indexPath], with: .automatic)

    calsforToday.text = calories
}

其他几点:

  1. 由于您已插入新行,因此无需重新加载整个表。重新加载会产生不必要的视觉效果
  2. 我建议你为数据模型创建一个结构而不是使用字典
  3. 每个部分都需要一个数组。
  4. struct FoodItem {
        var name: String
        var calories: String // This should probably be an Int
    }
    
    class FoodDiary: UITableViewController, AddRowDelegate {
    
        var tableData = Array(repeating: [FoodItem](), count: 3) 
    
        func numberOfSections(in tableView: UITableView) -> Int {
            return self.tableData.count
        }
    
        func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
            return self.tableData[section].count
        }
    
        func didAddRow(name: String, calories: String, section: Int) {
    
            let newItem = FoodItem(name:name, calories:calories)
            tableData[section].append(newItem)
            let indexPath = IndexPath(row: tableData[section].count-1, section: section)
            tableView.insertRows(at: [indexPath], with: .automatic)
    
            calsforToday.text = calories
        }
    
      //  Not shown; update your `cellForRow(at:)` to use the indexpath.section and row to get the required array and item. 
    }