Emma Campbell Emma Campbell - 1 month ago 13
iOS Question

Creating Self-Sizing Table View Cells Dependant on UILabel Height

I'm using Swift and am having some issues with making my table view cells self-sizing. From what I have read online the best way is to use:

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 138.0


I have put this code in but it hasn't seemed to work. I've tried it within viewDidLoad and also the cellForRowAt function. I'm not sure if I'm putting it in the wrong place or if I've set something up wrong. I have also got my auto constraint for the bottom of my UILabel set in relation to the bottom of the container with the expectation that the cell container will grow but the bottom of the UILabel to the bottom on the container will remain constant. Here is the code I currently have in my TableViewController:

class TableViewController: UITableViewController {

var data = [TextData]()

override func viewDidLoad() {
super.viewDidLoad()
loadSampleData()
}


func loadSampleData() {
let title1 = TextData(title: "Monday", blurb: "Today is Monday and it's a sunny day", photograph: #imageLiteral(resourceName: "mondayone"), article: "Monday Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat.")
let title2 = TextData(title: "Tuesday", blurb: "Today is Tuesday and it's a bit rainy but will clear up later on today", photograph: #imageLiteral(resourceName: "tuesdaytwo"), article: "Tuesday Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur." )
let title3 = TextData(title: "Wednesday", blurb: "Today is Wednesday and the umbrella should be handy because it's going to be stormy", photograph: #imageLiteral(resourceName: "wednesdaythree"), article: "Wednesday Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.")
let title4 = TextData(title: "Thursday", blurb: "Today is Thursday and it's sunny again, no need for any umbrella today!", photograph: #imageLiteral(resourceName: "thursdayfour"), article: "Thursday Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur.")

data += [title1, title2, title3, title4]
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}

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

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

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

let realData = data[(indexPath as NSIndexPath).row]

cell.titleLabel.text = realData.title
cell.bodyText.text = realData.blurb
cell.photo.image = realData.photograph

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = 138.0

return cell
}

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


Here is what my tableview currently looks like:
Current Table View

Here are my current constraints:
Constraints

Answer

Currently photo is preventing your cell from getting taller. Since photo is constrained to both the top and centre of the cell, making the cell taller would always make the image taller, but since the image has a height constraint, photo stops the cell from getting taller.

Remove the Photo.centerY constraint should allow the cell resize based on the label. Or, you could change the constaraint to an inequality (≤ or ≥, cant remember which). That should limit the cell from getting to small if there isn't already another constraint that does that.