使用sender.tag删除tableview中的行

时间:2017-08-21 14:56:27

标签: ios swift uitableview

我的tableView cellForRowAtIndexPath如下:

override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = tableView.dequeueReusableCell(withIdentifier: CheckoutAppointmentCell.reuseIdentifier) as! CheckoutAppointmentCell
    cell.appointment = appointments[indexPath.row]
    cell.checkoutButton.tag = indexPath.row
    cell.checkoutButton.addTarget(self, action: #selector(checkoutButtonTapped), for: .touchUpInside)
    return cell
}

然后我从tableViewdataSource删除约会,如此:

func checkoutButtonTapped(sender: UIButton) {
    appointments.remove(at: sender.tag)
    print(sender.tag)
    //self.tableView.beginUpdates()
    self.tableView.deleteRows(at: [IndexPath(row:sender.tag, section: 0)], with: .automatic)
    //self.tableView.endUpdates()
}

我第一次删除约会时,它运行正常。 sender.tag值应该是该值,并从tableView中删除正确的行。

删除第一行后,似乎删除了不正确的行。

我在调用reloadData()后尝试调用deleteRows,但动画不再出现。 beginUpdates()endUpdates()似乎也没有任何区别。

2 个答案:

答案 0 :(得分:6)

使用标记来跟踪索引路径是一种常见但非常差的做法。它在允许删除,插入或移动行的任何表视图中失败,因为除非使用reloadData完全重新加载表视图,否则剩余单元格现在具有无效标记。

不需要使用reloadData来保持标记最新的更好的解决方案是根据按钮的位置确定单元格按钮的indexPath

func checkoutButtonTapped(sender: UIButton) {
    let hitPoint = sender.convert(CGPoint.zero, to: tableView)
    if let indexPath = tableView.indexPathForRow(at: hitPoint) {
        // use indexPath to get needed data
    }
}

答案 1 :(得分:0)

我不知道这是不是好主意但是它似乎也可以使用CallBack Closures正常工作,因为使用标签并不是一个好主意。

正如@rmaddy建议的一些观点,我相应地更新了答案。

CustomCell类 - :

  import UIKit

class testingCell: UITableViewCell {

    var deleteCallBack : ((testingCell)->())?// CallBack function

    @IBOutlet weak var parentlabel: UILabel!

    @IBAction func deleteButton(_ sender: UIButton) {
        // Call your closure 
        if let callBack = deleteCallBack{
            callBack(self)
        }
    }
    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)

        // Configure the view for the selected state
    }

}

控制器类 - :

extension ViewController : UITableViewDelegate,UITableViewDataSource{

func numberOfSections(in tableView: UITableView) -> Int {
    return 1
}// Default is 1 if not implemented

func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int{
    // return number of rows in section
    return data.count
}


func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell{
    let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! testingCell
    cell.textLabel?.text = data[indexPath.row]

    cell.deleteCallBack = { [weak self] tableCell in
        //Print indexPath for selected Cell
        print(self?.dataTableView.indexPath(for: tableCell) as Any )

        if let selectedIndex  = self?.dataTableView.indexPath(for: tableCell) {
            // Print selected row
            print(selectedIndex.row)
            // delete row from array
            self?.data.remove(at: selectedIndex.row)
            // Get index row to be deleted from table
            let indePath = NSIndexPath(item: selectedIndex.row, section: selectedIndex.section)
            // delete row from table
            self?.dataTableView.deleteRows(at: [indePath as IndexPath], with: UITableViewRowAnimation.automatic)
        }

    }
    return cell
}


public func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat{
    // Return cell height
    return 100
}

删除后确实打印出正确的索引。