Mommy
Mommy

Reputation: 103

TableView with custom cells doesn't begin editing

I have a table view with custom cells in it. The cells have some buttons inside of them. When I press a button to make the table go to editing mode, it doesn't do anything.
If I set the cell's class to UITableViewCell then it works. The weird thing is that if I set the table view to be in editing mode by default, then when I launch the app the table is in editing mode. The only problem is when I press the button that is supposed to set it in editing mode.

Edit button:

@objc func didTapEdit(sender: AnyObject){
    if table.isEditing == false{
        table.isEditing = true
        print("okokokok")
    } else {
        table.isEditing = false
    }
}
//This works properly with table views with default cells

Table setup:

view.addSubview(table)
table.translatesAutoresizingMaskIntoConstraints = false
table.bottomAnchor.constraint(equalTo: view.bottomAnchor).isActive = true
table.topAnchor.constraint(equalTo: view.topAnchor, constant: navBarHeight).isActive = true
table.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 30).isActive = true
table.trailingAnchor.constraint(equalTo: view.trailingAnchor, constant: -30).isActive = true       

Custom cell:

contentView.addSubview(btn)
btn.translatesAutoresizingMaskIntoConstraints = false
btn.topAnchor.constraint(equalTo: topAnchor, constant: topSpace).isActive = true
btn.bottomAnchor.constraint(equalTo: bottomAnchor, constant: -5).isActive = true
btn.trailingAnchor.constraint(equalTo: trailingAnchor, constant: -5).isActive = true
let btnWidth = NSLayoutConstraint(item: btn, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: bounds.height-10)
btn.addConstraint(btnWidth)

I have mutiple buttons which I set up in the same way.

So where's the problem? I created other table views with custom cells and they all worked fine. Plus if I setup the table view to be in editing mode by default, when I run the app it is in editing mode and I can move the cells around! What is going on here? I think the problem might be with how I set the constraints but I have no clue really

Upvotes: 0

Views: 358

Answers (1)

DonMag
DonMag

Reputation: 77433

You add your btn to the cell's contentView, as you should. But then you constrain the button to the cell, which you should not do. Change your constraints to:

contentView.addSubview(btn)
btn.translatesAutoresizingMaskIntoConstraints = false

btn.topAnchor.constraint(equalTo: contentView.topAnchor, constant: topSpace).isActive = true
btn.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -5).isActive = true
btn.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5).isActive = true
let btnWidth = NSLayoutConstraint(item: btn, attribute: .width, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 0.0, constant: bounds.height-10)
btn.addConstraint(btnWidth)

As a side note, your btnWidth constraint looks very odd... if you want the button width to be the 10-pts less than the height of the cell, you should be able to get that with:

btn.widthAnchor.constraint(equalTo: contentView.heightAnchor, constant: -10)

Edit -- here is a complete example... adds a "Edit" button to the navigation bar that toggles between editing and not-editing:

class EditTestTableViewController: UITableViewController {

    lazy var editBtn = UIBarButtonItem(barButtonSystemItem: .edit, target: self, action: #selector(self.editTapped(_:)))
    lazy var doneBtn = UIBarButtonItem(barButtonSystemItem: .done, target: self, action: #selector(self.editTapped(_:)))

    override func viewDidLoad() {
        super.viewDidLoad()
        
        tableView.register(EditTestCell.self, forCellReuseIdentifier: "cell")
        
        self.navigationItem.rightBarButtonItem = editBtn
    }
    override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        return 8
    }
    override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
        let c = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! EditTestCell
        c.label.text = "\(indexPath)"
        return c
    }
    @objc func editTapped(_ sender: Any) -> Void {
        tableView.isEditing.toggle()
        self.navigationItem.rightBarButtonItem = tableView.isEditing ? doneBtn : editBtn
    }
    override func tableView(_ tableView: UITableView, moveRowAt sourceIndexPath: IndexPath, to destinationIndexPath: IndexPath) {
        // handle moving row...
    }
    override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
        // handle delete row...
    }
    
}

and a simple custom cell class:

class EditTestCell: UITableViewCell {
    let btn = UIButton()
    let label = UILabel()
    
    override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)
        commonInit()
    }
    required init?(coder: NSCoder) {
        super.init(coder: coder)
        commonInit()
    }
    func commonInit() -> Void {
        btn.backgroundColor = .red
        btn.setTitle("Test", for: [])
            
        label.backgroundColor = .green
        
        contentView.addSubview(label)
        label.translatesAutoresizingMaskIntoConstraints = false
        contentView.addSubview(btn)
        btn.translatesAutoresizingMaskIntoConstraints = false
        
        NSLayoutConstraint.activate([
            btn.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 12.0),
            btn.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -12.0),
            btn.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -5.0),
            btn.widthAnchor.constraint(equalTo: contentView.heightAnchor, constant: -10.0),
            
            label.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 5.0),
            label.centerYAnchor.constraint(equalTo: contentView.centerYAnchor),
        ])
    }
}

enter image description here enter image description here

Upvotes: 1

Related Questions