ios - 从 UITableView 中删除自定义 View

标签 ios iphone swift uitableview swift4

我向左滑动以删除一个单元格,它是 Swift 3 中的自定义 View 。

单元格是:

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);
    }

然后在我的 TableView Controller 中我有:

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;
}

TableView Controller 中的删除发生在这里:

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];

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

我该如何解决这个问题?我也在使用自定义单元格 View 。

一个例子是我有 6 行,前 4 行是可见的。删除第一行会使第 4 行和第 5 行相同。正如最后一个可见行也成为第一个不可见行。 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。

最佳答案

TableView 自定义单元格中,如果您从 storyboardXIB 添加 views,那么它会在滚动时被删除但是,如果您以编程方式添加 views,则必须从 tableViewCell 中删除 View :

cellForRow 中使用以下代码:

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

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

class myCustomCell: UITableViewCell {

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

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

}

以上代码将从单元格中删除所有 subview 。

查看以下链接以获得更多答案:

编辑

我在 tableView 中使用字符串 ArrayswipeDelete 功能尝试了以下代码:

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;
}

仍然像上面一样工作。

关于ios - 从 UITableView 中删除自定义 View ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51184331/

相关文章:

ios - 禁用内部时嵌套 UITableViews : a way to scroll only the outer UITableView,?

ios - 适用于 iOS 的最佳归档库

iphone - 从后台线程访问 NSManagedObject

ios - 如何在特定日期前 2 天触发 UserNotifications

iphone - iPhone 4分辨率

ios - 导航 Controller 和选项卡 Controller

ios - 向客户分发我的 iOS 应用程序的最佳方式是什么?

ios - 导航栏的实时模糊效果 - 状态栏无法进入

ios - Xcode 10、Swift 4 - 如何跨多个 View Controller 传输数据?

iphone - 将 Twitter 与 iOS 集成时回调 url 不起作用