代码之家  ›  专栏  ›  技术社区  ›  cdub

从UITableView中删除自定义视图

  •  1
  • cdub  · 技术社区  · 6 年前

    我向左滑动以删除Swift 3中的自定义视图单元格。

    该单元为:

    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行是可见的。删除第一行会使第四行和第五行相同。正如在最后一个可见行中一样,该行也将成为第一个不可见行。prepareforeuse可能工作不正常。

    delete可以从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,只是升级到了swift4.1。

    2 回复  |  直到 6 年前
        1
  •  2
  •   Amit    6 年前

    在里面 TableView 自定义单元格(如果要添加) views 从…起 storyboard XIB 然后它会在滚动时被删除,但如果您正在添加 意见 然后,您必须以编程方式从 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 swipeDelete 功能性 tableView :

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

    当我开始滑动时,删除 桌面视图 细胞 string 数据是正确的,但是 indexPath 价值不会改变。当我滚动页面时,它会改变 桌面视图 。这在逻辑上是正确的,因为删除后字符串数据索引已更改,并且当重新使用单元格时,新索引将可见。

    使用SwipCellKit编辑:

    将与您相同的代码用于 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;
    }
    

    仍然和上面一样工作。

        2
  •  1
  •   denvdancsk    6 年前

    问题在于你的细胞是如何被重用的。将此行代码添加到表格单元格类:

      override func prepareForReuse() {
        super.prepareForReuse()
    
            atest.text = nil
            btest.text = nil
      }