0

I am trying to setup dynamic height for my custom table view cell...programatically.

There are many tutorials for doing it inside the storyboard, but this is about a pure programmatic solution:

class CustomTableViewCell: UITableViewCell {

    var container: UIView = {
        let view = UIView()
        view.translatesAutoresizingMaskIntoConstraints =  false
        return view
    }()

    override func awakeFromNib() {
        super.awakeFromNib()

        self.setupView()
        self.addConstraints()
    }

    func setupView() {
        self.contentView.addSubview(self.container)
        self.container.backgroundColor = UIColor.cyan
    }

    func addConstraints() {
        self.container.leadingAnchor.constraint(equalTo: self.contentView.leadingAnchor, constant: 0).isActive = true
        self.container.trailingAnchor.constraint(equalTo: self.contentView.trailingAnchor, constant: 0).isActive = true
        self.container.topAnchor.constraint(equalTo: self.contentView.topAnchor, constant: 0).isActive = true
        self.container.bottomAnchor.constraint(equalTo: self.contentView.bottomAnchor, constant: 0).isActive = true
        self.container.heightAnchor.constraint(equalToConstant: 200)
    }

    override func setSelected(_ selected: Bool, animated: Bool) {
        super.setSelected(selected, animated: animated)
    }

}

And my view where i am registering it:

class CustomViewController: UIViewController {

    var data: [Post] = []

    let tableview: UITableView = {
        let tableview = UITableView()
        tableview.translatesAutoresizingMaskIntoConstraints =  false
        return tableview
    }()

    override func viewDidLoad() {
        super.viewDidLoad()

        self.setupView()
        self.addConstraints()
        self.getData()
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }

    func setupView() {
        self.view.addSubview(self.tableview)
        self.tableview.delegate = self
        self.tableview.dataSource = self
        self.tableview.register(UINib(nibName: "CustomTableViewCell", bundle: nil), forCellReuseIdentifier: "CellCustom")
        self.tableview.estimatedRowHeight = 100
        self.tableview.rowHeight = UITableViewAutomaticDimension
    }

    func addConstraints() {
        self.tableview.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 40).isActive = true
        self.tableview.trailingAnchor.constraint(equalTo: self.view.trailingAnchor, constant: -40).isActive = true
        self.tableview.topAnchor.constraint(equalTo: self.view.topAnchor, constant: 40).isActive = true
        self.tableview.bottomAnchor.constraint(equalTo: self.view.bottomAnchor, constant: -40).isActive = true
    }

    func getData() {
        // some networking stuff
    }

}

extension CustomViewController: UITableViewDelegate {

}

extension StreamViewController: UITableViewDataSource {

    func numberOfSections(in tableView: UITableView) -> Int {
        return 1
    }

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

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

        return cell
    }

}

I am trying to just simply resize my custom tableview cell bases on its height constraint:

self.container.heightAnchor.constraint(equalToConstant: 200)

But this not work.. the custom tableview cell stays at "44"..

Anybody could tell me what is wrong with my pure programmtic solution?

Thanks and Greetings

Creative crypter
  • 1,348
  • 6
  • 30
  • 67
  • 1
    `awakeFromNib` doesn't get called unless you are creating your cell from a nib/storyboard. Override `init(style:reuseIdentifier:)` and setup your constraints there. You also need to pass the cell class and not a nib when you register in the table. – dan Sep 11 '17 at 22:21
  • @dan That should be an answer, not a comment. – rmaddy Sep 11 '17 at 22:24
  • @dan awakeFromNib gets called, because when i print something, it show up in the console.. can you please give some more details? :/ – Creative crypter Sep 11 '17 at 22:25
  • @dan could you refer to your solution more in detail based on my code? – Creative crypter Sep 11 '17 at 22:37
  • `awakeFromNib ` is working for this code, because the way tableview register its cell. I guess @Creativecrypter 's code is not quite programatically. Might use `self.tableview.register(CustomTableViewCell.self, forCellReuseIdentifier: "CellCustom") ` instead. – antonio081014 Sep 11 '17 at 23:52

2 Answers2

2

The problem seems to be that the height constraint is not active

func addConstraints() {
    ...
    self.container.heightAnchor.constraint(equalToConstant: 200)
}

Thats why the UITableViewAutomaticDimension does not work.

Change it to self.container.heightAnchor.constraint(equalToConstant: 200).isActive = true and it should work

hfehrmann
  • 457
  • 3
  • 13
0

Just dynamically calculate the height for each cell.

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

PS: It's better to save this height value, so you don't need to recalculate it over and over again.

antonio081014
  • 3,553
  • 1
  • 30
  • 37