有没有一种简单的方法可以从UITableView中删除特定的自定义单元格? [英] Is there a simple way to delete specific custom cells from a UITableView?
问题描述
我正在尝试在表格视图中实例化空的买方单元格(自定义单元格),然后让用户填充买方的名称.当用户按下某行/单元格的删除按钮时,无论是否已填充该行的文本字段,都应删除相应的行/单元格.显然,我没有得到期望的行为.例如,当我按Delete Row0(其文本字段显示"Buyer 0")并且重新加载表格视图时,Buyer 0仍然存在,但是最后一个空的Buyer单元之一被删除了.
I am trying to instantiate empty Buyer cells (custom cell) in my table view and then have the user populate the buyers' names. When the user presses the delete button for a row/cell, it should delete the corresponding row/cell regardless of whether or not the textfield for that row has been populated or not. Clearly, I am not getting the desired behavior. For example, when I press delete Row0 (whose textfield says "Buyer 0") and the tableview reloads, Buyer 0 is still there, but one of the empty Buyer cells at the end gets deleted instead.
import UIKit
class EntryAlertViewController: UIViewController {
//Fields/Table
@IBOutlet weak var itemField: UITextField!
@IBOutlet weak var priceField: UITextField!
@IBOutlet weak var tableView: UITableView!
//Visual Components
@IBOutlet weak var mainView: UIView!
@IBOutlet weak var titleView: UIView!
@IBOutlet weak var splitItemButton: UIButton!
@IBOutlet weak var cancelButton: UIButton!
@IBOutlet weak var addItemButton: UIButton!
//Commonly Used Objects/Variables
var potentialBuyers: [String] = []
override func viewDidLoad() {
super.viewDidLoad()
potentialBuyers.append("")
tableView.dataSource = self
tableView.register(UINib(nibName: "BuyerCell", bundle: nil), forCellReuseIdentifier: "ReusableCell")
}
override func viewWillAppear(_ animated: Bool) {
}
@IBAction func splitItemPressed(_ sender: UIButton) {
potentialBuyers.append("")
tableView.reloadData()
}
}
这是tableview数据源和删除按钮委托.
Here are the tableview datasource and the delete button delegate.
extension EntryAlertViewController: UITableViewDataSource, DeleteButtonDelegate {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return potentialBuyers.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ReusableCell", for: indexPath) as! BuyerCell
cell.deleteButtonDelegate = self
cell.indexPath = indexPath
cell.nameField.text = cell.buyerName
if potentialBuyers.count == 1 {
cell.deleteButton.isHidden = true
} else {
cell.deleteButton.isHidden = false
}
return cell
}
func deletePressed(index: Int) {
potentialBuyers.remove(at: index)
tableView.reloadData()
}
}
这是我的BuyerCell类,带有UITextFieldDelegate作为扩展.
And here is my BuyerCell class with the UITextFieldDelegate as an extension.
import UIKit
protocol DeleteButtonDelegate {
func deletePressed(index: Int)
}
class BuyerCell: UITableViewCell {
@IBOutlet weak var deleteButton: UIButton!
@IBOutlet weak var nameField: UITextField!
var deleteButtonDelegate: DeleteButtonDelegate!
var indexPath: IndexPath!
var buyerName: String?
override func awakeFromNib() {
super.awakeFromNib()
self.nameField.delegate = self
}
@IBAction func deletePressed(_ sender: UIButton) {
//print the indexPath.row that this was pressed for
print("delet pressed for \(indexPath.row)")
self.deleteButtonDelegate?.deletePressed(index: indexPath.row)
}
override func setSelected(_ selected: Bool, animated: Bool) {
super.setSelected(selected, animated: animated)
// Configure the view for the selected state
}
}
extension BuyerCell: UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
print("textFieldDidBeginEditing")
buyerName = nameField.text
}
func textFieldDidEndEditing(_ textField: UITextField) {
print("textFieldDidEndEditing")
buyerName = nameField.text
}
}
推荐答案
您的代码中存在一个主要问题.您没有更新数据模型,因此当用户滚动时,单元格中的更改会丢失.
There is a major issue in your code. You are not updating the data model so the changes in the cells are lost when the user scrolls.
而不是相当 objective-c-ish 协议/委托更加方便和高效.您可以使用一个回调来更新模型和删除单元格.
Rather then quite objective-c-ish protocol/delegate in Swift callback closures are much more convenient and efficient. You can use one callback for both updating the model and deleting the cell.
用
class BuyerCell: UITableViewCell {
@IBOutlet weak var deleteButton: UIButton!
@IBOutlet weak var nameField: UITextField!
var callback : ((UITableViewCell, String?) -> Void)?
override func awakeFromNib() {
super.awakeFromNib()
self.nameField.delegate = self
}
@IBAction func deletePressed(_ sender: UIButton) {
callback?(self, nil)
}
}
extension BuyerCell: UITextFieldDelegate {
func textFieldDidBeginEditing(_ textField: UITextField) {
print("textFieldDidBeginEditing")
callback?(self, nameField.text)
}
func textFieldDidEndEditing(_ textField: UITextField) {
print("textFieldDidEndEditing")
callback?(self, nameField.text)
}
}
在 cellForRow
中的控制器中分配回调并处理操作.如果对单元格进行重新排序,插入或删除,这些动作也可以可靠地工作.
In the controller in cellForRow
assign the callback and handle the actions. The actions work also reliably if cells are reordered, inserted or deleted.
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ReusableCell", for: indexPath) as! BuyerCell
let buyerName = potentialBuyers[indexPath.row]
cell.nameField.text = buyerName
cell.callback = { [unowned self] cCell, cName in
let currentIndexPath = tableView.indexPath(for: cCell)!
if let name = cName {
self.potentialBuyers[currentIndexPath.row] = name
} else {
self.potentialBuyers.remove(at: currentIndexPath.row)
tableView.deleteRows(at: [currentIndexPath], with: .fade)
}
}
cell.deleteButton.isHidden = potentialBuyers.count == 1
return cell
}
这篇关于有没有一种简单的方法可以从UITableView中删除特定的自定义单元格?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!