Search code examples
iosuitableviewnslayoutconstraintios-autolayout

Why UITableViewCell dynamic view constraint not working properly?


I am trying to create UIButton inside the UITableViewCell using following way

UITableView configuration :

self.tableView.estimatedRowHeight = 1
self.tableView.rowHeight = UITableView.automaticDimension
self.tableView.delegate = self
self.tableView.dataSource = self     

UITableViewCell:

func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {              
let uiTableViewCell = UITableViewCell(style: .default, reuseIdentifier: "More");
uiTableViewCell.contentView.backgroundColor = .yellow
let moreBtn = UIButton(type: .system)
moreBtn.setTitle("More", for: .normal)
moreBtn.setTitleColor(.white, for: .normal)
moreBtn.backgroundColor = UIColor.init(hexString: "#2A1771")

moreBtn.translatesAutoresizingMaskIntoConstraints = false
uiTableViewCell.contentView.addSubview(moreBtn)

let leading = NSLayoutConstraint(item: moreBtn, attribute: .leading, relatedBy: .equal, toItem: uiTableViewCell.contentView, attribute: .leading, multiplier: 1, constant: 16)
let trailing = NSLayoutConstraint(item: moreBtn, attribute: .trailing, relatedBy: .equal, toItem: uiTableViewCell.contentView, attribute: .trailing, multiplier: 1, constant: 16)
let top = NSLayoutConstraint(item: moreBtn, attribute: .top, relatedBy: .equal, toItem: uiTableViewCell.contentView, attribute: .top, multiplier: 1, constant: 16)
let bottom = NSLayoutConstraint(item: moreBtn, attribute: .bottom, relatedBy: .equal, toItem: uiTableViewCell.contentView, attribute: .bottom, multiplier: 1, constant: 16)

let height = NSLayoutConstraint(item: moreBtn, attribute: .height, relatedBy: .equal, toItem: nil, attribute: .notAnAttribute, multiplier: 1, constant: 52)

uiTableViewCell.contentView.addConstraints([leading,top,trailing,bottom,height])
NSLayoutConstraint.activate([leading,top,trailing,bottom,height])

return uiTableViewCell

}

See this following image.. Why more button going outside from contentView

enter image description here


Solution

  • Your constraints are saying the the button's trailing edge should be 16 more than the content view trailing edge (The constant is +16) and similarly for the bottom edge.

    You can either swap the item and toItem properties in those constraints or use -16 as the constant.

    You will also have a problem with adding the button in cellForRow as cells are reused when the table view scrolls, resulting in multiple buttons being added to a cell. You should add the button in the cell itself, either in the initialiser or in awakeFromNib