[英]Add and delete cell from table view in swift
我在單元格中有一個表格視圖,我有兩個文本字段,用戶可以在其中輸入數據。 最初我顯示5個單元格。 有一個按鈕,當用戶單擊它時,將在表視圖中添加一個單元格。 現在,當我按下按鈕時,當文本字段為空時會添加一個單元格。 但是,當我在所有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)
}
問題在於您創建用於插入新行的indexPath
的方式,請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(row: allCellsText.count+1, section: 0)
創建IndexPath
。 在插入和缺失tableView
必須與一致的dataSource
-如果你添加一個新行時, numberOfRowsInSection
被一個增加了。 現在,按照您的預期,將numberOfCell
增加一,但是您嘗試將新行添加到由allCellsText.count+1
確定的allCellsText.count+1
。 問題在於allCellsText.count
與numberOfCell
變量不一致(請注意,每次調用textFieldDidEndEditing
時allCellsText.count
追加一個新字符串)。
編輯
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)
}
如果要使用按鈕刪除tableviewCell,則任何允許刪除行的表視圖
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()
}
}
您做錯了。 您已在此處將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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.