有没有一种简单的方法可以从UITableView中删除特定的自定义单元格? [英] Is there a simple way to delete specific custom cells from a UITableView?

查看:53
本文介绍了有没有一种简单的方法可以从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屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆