在swift

时间:2018-02-13 09:09:55

标签: ios uitableview

我在单元格中有一个表格视图,我有两个文本字段,用户可以在其中输入数据。最初我显示了5个细胞。有一个按钮,当用户单击它时,在表视图中添加一个单元格。现在,当我点击一个按钮时,它会在textfields为空时添加一个单元格。但是当我在所有5个单元格文本字段中添加数据而不是通过显示此错误来点击添加按钮应用程序崩溃时,Terminating app due to uncaught exception 'NSInternalInconsistencyException', reason: 'attempt to insert row 10 into section 0, but there are only 6 rows in section 0 after the update'

代码是尝试添加和删除单元格,

extension FlashCardViewController: UITableViewDelegate,UITableViewDataSource, UITextFieldDelegate{

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

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

    //cell.termTxt.delegate = self
    //allCellsText[indexPath.row] = cell.termTxt.text!
   // cell.definitionTxt.delegate = self
    return cell
}


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 115
}

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == .delete{
        numberOfCell -= 1
        allCellsText.remove(at: indexPath.row)
        flashCardTableView.beginUpdates()
        flashCardTableView.deleteRows(at: [indexPath], with: .automatic)
        flashCardTableView.endUpdates()
    }
}

func textFieldDidEndEditing(_ textField: UITextField) {
    allCellsText.append(textField.text!)
    print(allCellsText)
}

}

添加按钮的代码是这个,

 @IBAction func addCardBtnTapped(_ sender: Any) {

    numberOfCell += 1
    let indexPath = IndexPath(row: allCellsText.count+1, section: 0)
    flashCardTableView.beginUpdates()
    flashCardTableView.insertRows(at: [indexPath], with: .automatic)
    flashCardTableView.endUpdates()
    view.endEditing(true)
}

当我删除任何单元格时,它给出了索引超出范围的错误。我怎样才能实现这一目标?视图控制器看起来像这样, enter image description here

3 个答案:

答案 0 :(得分:1)

问题在于您创建indexPath以插入新行的方式,并根据此修复它:

@IBAction func addCardBtnTapped(_ sender: Any) {

    numberOfCell += 1
    // create indexPath from numberOfCell, not from allCellsText.count
    let indexPath = IndexPath(row: numberOfCell - 1, section: 0)
    flashCardTableView.beginUpdates()
    flashCardTableView.insertRows(at: [indexPath], with: .automatic)
    flashCardTableView.endUpdates()
    view.endEditing(true)
}

问题在于使用IndexPath创建IndexPath(row: allCellsText.count+1, section: 0)tableView HAVE 上的插入和删除与dataSource保持一致 - 如果添加新行,numberOfRowsInSection也要增加1。现在,在您的情况下,您将numberOfCell增加1,就像您应该做的那样,但是您尝试在由allCellsText.count+1确定的indexPath处添加新行。问题是allCellsText.countnumberOfCell变量不一致(请注意,每次textFieldDidEndEditing调用时都附加一个新字符串。)

修改

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

 func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = flashCardTableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! FlashCardTableViewCell
    // configure it with the backing data
    cell.termTxt.text = allCellsTermText[indexPath.row]
    cell.definitionTxt.text = allCellsDefinitionText[indexPath.row]

    // now instead of this you will have to find a way how you will be
    // able to determine the row which needs to be changed and change the model
    // cell.termTxt.delegate = self
    // cell.definitionTxt.delegate = self
    return cell
}


func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return 115
}

func tableView(_ tableView: UITableView, canEditRowAt indexPath: IndexPath) -> Bool {
    return true
}

func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {

    if editingStyle == .delete {
        allCellsTermText.remove(at: indexPath.row)
        allCellsDefinitionText.remove(at: indexPath.row)
        flashCardTableView.deleteRows(at: [indexPath], with: .automatic)
    }
}

func textFieldDidEndEditing(_ textField: UITextField) {
    // you should not append here, this will add a new row, you have to UPDATE the proper text 
    // allCellsText.append(textField.text!)
}


@IBAction func addCardBtnTapped(_ sender: Any) {

    // create a new row by appending new empty strings
    allCellsTermText.append("")
    allCellsDefinitionText.append("")

    let indexPath = IndexPath(row: allCellsTermText.count - 1, section: 0)
    flashCardTableView.insertRows(at: [indexPath], with: .automatic)
    view.endEditing(true)
}

答案 1 :(得分:1)

如果要使用按钮删除tableviewCell,则任何允许删除行的表视图

Image TableViewCell delete with button

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

        cell.deleteButton.addTarget(self, action: #selector(nHapusTap(_:)), for: .touchUpInside)            

        return cell
    }

  @objc func nHapusTap(_ sender: UIButton) {
        let hitPoint = sender.convert(CGPoint.zero, to: tableView)
        if let indexPath = tableView.indexPathForRow(at: hitPoint) {

            self.dataArray.remove(at: indexPath.row)
            tableView.beginUpdates()
            tableView.deleteRows(at: [indexPath], with: .automatic)
            tableView.endUpdates()

        }

    }

答案 2 :(得分:0)

你做错了。您已在此处将self作为委托添加到termtxt和definitiontxt。

cell.termTxt.delegate = self
    cell.definitionTxt.delegate = self

在这些输入框中结束编辑的次数很多时,您的委托方法会在您将文本附加到数组中时被击中。

func textFieldDidEndEditing(_ textField: UITextField) {
    allCellsText.append(textField.text!)
    print(allCellsText)
}

当您调用添加行按钮时,allCellsText大小为10,因为已从两种类型的输入框调用endEditing。 (10不正确,你不能在第5行后添加第10行)。

let indexPath = IndexPath(row: allCellsText.count+1, section: 0)

解决方案: 在allCellsText数组中追加任何内容之前,在委托方法中添加一些检查,或者在addCardBtnTapped函数中更新逻辑,从allCellsText箭头中删除依赖项。 使用类似的东西:

let indexPath = IndexPath(row: numberOfCell+1, section: 0)