从UITableView删除自定义视图

时间:2018-07-05 06:05:10

标签: ios iphone swift uitableview swift4

我向左滑动以删除Swift 3中作为customview的单元格。

该单元格是:

class CustomTableCell: SwipeTableViewCell
{
    public var atest = UILabel();
    public var btest = UILabel();

    var animator: Any?

    override init(style: UITableViewCellStyle, reuseIdentifier: String!)
    {
        super.init(style: style, reuseIdentifier: reuseIdentifier);

        let height = 140;

        atest = UILabel(frame: CGRect(x: 20 + (activityWidth / 2), y: 72, width: (activityWidth / 2) - 10, height: 30));

        btest = UILabel(frame: CGRect(x: 20 + (activityWidth / 2), y: 102, width: (activityWidth / 2) - 10, height: 30));

        self.contentView.addSubview(atest);
        self.contentView.addSubview(btest);
    }

然后在我的表视图控制器中,我拥有:

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

    cell.atest.text = "text from an array at indexpath.row";
    cell.btest.text = "another different text from an array";

    return cell;
}

在表视图控制器中的删除发生在这里:

func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]?
{
    let delete = SwipeAction(style: .destructive, title: "Delete")
    {
        action, indexPath in
        print("delete button tapped");

        // self.table.deleteRows(at: [indexPath], with: .none);

        // database is a string index array
        self.database.remove(at: indexPath.row);

        if (self.database.count == 0)
        {
            self.noText.isHidden = false;
            self.footer.isHidden = false;

            self.table.tableFooterView = self.footer;
        }

        // self.table.setNeedsDisplay();
    }

    delete.backgroundColor = UIColor.red;

    return [delete];

我通过向左滑动来执行删除操作,它可以正确删除所有内容。我的问题是,删除操作会使折叠下的所有表格视图单元格与最后一个可见单元格相同。

该如何解决?我也在使用自定义单元格视图。

一个例子是我有6行,可见前4行。删除第一行会使第四行和第五行相同。与最后一个可见行一样,它也成为第一个不可见行。 prepareForReuse可能无法正常工作。

删除有效,从6行增加到5行,但下面是一个示例。

 UITableView
 First row label         A
 Second row label        B
 Third row label         C
 Fourth row label        D (last visible row)
 Fifth row label         E (first non visible row)
 Sixth row label         F

通过滑动删除第一行,将创建以下新的UITableView:

 UITableView
 Second row label        B
 Third row label         C
 Fourth row label        D
 Fourth row label        D (last visible row)
 Fifth row label         E (first non visible row)

可重复使用的单元无法正常工作。

我不使用awakeFromNib,也只是升级到swift 4.1。

2 个答案:

答案 0 :(得分:2)

TableView自定义单元格中,如果您要从viewsstoryboard添加XIB,则在滚动时将其删除,但是如果您以编程方式添加views,则您必须从tableViewCell中删除视图:

使用cellForRow中的以下代码:

for label in cell.subviews {
    if let mylabel = label as? UILabel {
        mylabel.removeFromSuperview()
    }
}

或者您可以在customCellClass方法中使用以下代码prepareForReuse

class myCustomCell: UITableViewCell {

    override func prepareForReuse() {
        super.prepareForReuse()
        for view in self.subviews {
            view.removeFromSuperview()
        }
    }

    override func awakeFromNib() {
        super.awakeFromNib()
        // Initialization code
    }

}

以上代码将从单元格中删除所有子视图。

检查以下链接以获取更多答案:

编辑

我在下面的代码中尝试了Array中具有字符串swipeDeletetableView功能的代码:

class ViewController: UIViewController {

    @IBOutlet weak var sampleTableView: UITableView!

    var nameArray = ["Snoop", "Sarah", "Fido", "Mark", "Jill", "Parague", "London", "Barcelona", "Italy", "France", "Eiffiel", "Tower", "Paris", "Europe", "Amsterdam", "Zurich", "Germany", "Munich", "Milan", "Venice", "Switzerland", "Brussels"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
}

extension ViewController: UITableViewDataSource, UITableViewDelegate {
    func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return nameArray.count
    }

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

        cell.textLabel?.text = nameArray[indexPath.row] + " - " + String(describing: indexPath.row)

        return cell
    }

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

    func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCellEditingStyle, forRowAt indexPath: IndexPath) {
        if (editingStyle == UITableViewCellEditingStyle.delete) {
            // handle delete (by removing the data from your array and updating the tableview)
            tableView.beginUpdates()
            nameArray.remove(at: indexPath.row)
            tableView.deleteRows(at: [indexPath], with: .automatic)
            tableView.endUpdates()
        }
    }
}

当我开始滑动删除tableView单元格时,string数据是正确的,但是indexPath的值不变。当我滚动tableView时,它会改变。从逻辑上讲这是正确的,因为删除后字符串数据索引已更改,并且当单元被重用时新的索引将可见。

使用SwipwCellKit编辑:

SwipeCellKit中使用了与您相同的代码:

我的ViewController

class ViewController: UIViewController {

    @IBOutlet weak var sampleTableView: UITableView!

    var nameArray = ["Snoop", "Sarah", "Fido", "Mark", "Jill", "Parague", "London", "Barcelona", "Italy", "France", "Eiffiel", "Tower", "Paris", "Europe", "Amsterdam", "Zurich", "Germany", "Munich", "Milan", "Venice", "Switzerland", "Brussels"]

    override func viewDidLoad() {
        super.viewDidLoad()
        // Do any additional setup after loading the view, typically from a nib.
    }
}

extension ViewController : UITableViewDataSource, UITableViewDelegate, SwipeTableViewCellDelegate {

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

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

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

        cell.delegate = self

        cell.atest.text = nameArray[indexPath.row] + " - " + String(describing: indexPath.row)
        cell.btest.text = "another different text from an array";

        return cell;
    }

    func tableView(_ tableView: UITableView, editActionsForRowAt indexPath: IndexPath, for orientation: SwipeActionsOrientation) -> [SwipeAction]?
    {
        let delete = SwipeAction(style: .destructive, title: "Delete")
        {
            action, indexPath in
            print("delete button tapped")

            self.nameArray.remove(at: indexPath.row)

            self.sampleTableView.deleteRows(at: [indexPath], with: .none)
        }

        delete.backgroundColor = UIColor.red;

        return [delete];
    }
}

我的CustomTableViewCell

class CustomTableCell: SwipeTableViewCell {

    public var atest = UILabel()
    public var btest = UILabel()

    var animator: Any?

    override func awakeFromNib() {
        atest = UILabel(frame: CGRect(x: 20 , y: 2, width: 200, height: 30));

        btest = UILabel(frame: CGRect(x: 20 , y: 32, width: 200, height: 30));

        self.contentView.addSubview(atest);
        self.contentView.addSubview(btest);
    }

}

工作方式与第一次编辑相同。

编辑

CustomTableViewCell使用init

class CustomTableViewCell: SwipeTableViewCell {

    public var atest = UILabel();
    public var btest = UILabel();

    var animator: Any?

    override init(style: UITableViewCellStyle, reuseIdentifier: String!)
    {
        super.init(style: style, reuseIdentifier: reuseIdentifier)


        atest = UILabel(frame: CGRect(x: 20 , y: 2, width: 100, height: 30))

        btest = UILabel(frame: CGRect(x: 20 , y: 32, width: 100, height: 30))

        self.contentView.addSubview(atest)
        self.contentView.addSubview(btest)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        fatalError("init(coder:) has not been implemented")
    }
}

cellForRow中的更改:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
    let cell = CustomTableViewCell.init(style: .default, reuseIdentifier: "reuseIdentifier")

    cell.delegate = self

    cell.atest.text = nameArray[indexPath.row] + " - " + String(describing: indexPath.row)
    cell.btest.text = "another different text from an array";

    return cell;
}

仍然与上述相同。

答案 1 :(得分:1)

问题在于您的单元如何被重用。将这行代码添加到表单元格类中:

  override func prepareForReuse() {
    super.prepareForReuse()

        atest.text = nil
        btest.text = nil
  }