3

I have a view controller with a table view. Now I want to set up a self sizing cell. The cell should contains three or more Labels. If I have just two Labels, the self sizing cell works perfectly. But as soon as I add the third Label the text in the second label doesn't wrap anymore. and below the third label is a lot of free space. Screenshot http://stefangerard.com/images/selfSizing.png These are the constraints of the three Labels.

  • first Label (Hello CustomCell)

constraint first Label http://stefangerard.com/images/constraint1.png

  • second Label (Far curiosity...)

constraint second Label http://stefangerard.com/images/constraint2.png

  • third Label (Concerns greatest...)

constarint third Label http://stefangerard.com/images/constraint3.png

In my ViewController I just set up the cell and call these two lines in the viewDidLoad() that the cell calculate its height by itself.

self.tableView.estimatedRowHeight = 50.0
self.tableView.rowHeight = UITableViewAutomaticDimension

My ViewController looks like this:

import UIKit
class CustomViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var tableView: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.estimatedRowHeight = 50.0
    self.tableView.rowHeight = UITableViewAutomaticDimension
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    self.tableView.reloadData()
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var someRandomText1 = "Far curiosity incommode now led smallness allowance. Favour bed assure son things yet. She consisted consulted elsewhere happiness disposing household any old the. Widow downs you new shade drift hopes small. So otherwise commanded sweetness we improving. Instantly by daughters resembled unwilling principle so middleton. Fail most room even gone her end like. Comparison dissimilar unpleasant six compliment two unpleasing any add. Ashamed my company thought wishing colonel it prevent he in. Pretended residence are something far engrossed old off."
    var someRandomText2 = "Concerns greatest margaret him absolute entrance nay. Door neat week do find past he. Be no surprise he honoured indulged. Unpacked endeavor six steepest had husbands her. Painted no or affixed it so civilly. Exposed neither pressed so cottage as proceed at offices. Nay they gone sir game four. Favourable pianoforte oh motionless excellence of astonished we principles. Warrant present garrets limited cordial in inquiry to. Supported me sweetness behaviour shameless excellent so arranging."

    var cell = tableView.dequeueReusableCellWithIdentifier("customCell", forIndexPath: indexPath) as! CustomTableViewCell
    cell.headlineLabel.text = "Hello CustomCell"
    cell.text1Label.text = someRandomText1
    cell.text2Label.text = someRandomText2
    return cell
}
}

Can anybody help me out with this problem?

Thank You!

EDIT

You can download the project here: https://github.com/stefocdp/selfSizingCell

stefOCDP
  • 803
  • 2
  • 12
  • 20

2 Answers2

2

I fixed it by adding this line of code to the cellForRowAtIndexPath function

cell.layoutIfNeeded()

My ViewController looks like this now:

import UIKit

class CustomViewController: UIViewController, UITableViewDataSource, UITableViewDelegate {

@IBOutlet weak var tableView: UITableView!

override func viewDidLoad() {
    super.viewDidLoad()

    self.tableView.estimatedRowHeight = 50
    self.tableView.rowHeight = UITableViewAutomaticDimension
}

override func didReceiveMemoryWarning() {
    super.didReceiveMemoryWarning()
    // Dispose of any resources that can be recreated.
}

override func viewDidAppear(animated: Bool) {
    super.viewDidAppear(animated)

    self.tableView.reloadData()
}

func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
    return 1
}

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var someRandomText1 = "Far curiosity incommode now led smallness allowance. Favour bed assure son things yet. She consisted consulted elsewhere happiness disposing household any old the. Widow downs you new shade drift hopes small. So otherwise commanded sweetness we improving. Instantly by daughters resembled unwilling principle so middleton. Fail most room even gone her end like. Comparison dissimilar unpleasant six compliment two unpleasing any add. Ashamed my company thought wishing colonel it prevent he in. Pretended residence are something far engrossed old off."
    var someRandomText2 = "Concerns greatest margaret him absolute entrance nay. Door neat week do find past he. Be no surprise he honoured indulged. Unpacked endeavor six steepest had husbands her. Painted no or affixed it so civilly. Exposed neither pressed so cottage as proceed at offices. Nay they gone sir game four. Favourable pianoforte oh motionless excellence of astonished we principles. Warrant present garrets limited cordial in inquiry to. Supported me sweetness behaviour shameless excellent so arranging."

    var cell = tableView.dequeueReusableCellWithIdentifier("customCell", forIndexPath: indexPath) as! CustomTableViewCell
    cell.headlineLabel.text = "Hello CustomCell"
    cell.text1Label.text = someRandomText1
    cell.text2Label.text = someRandomText2
    cell.layoutIfNeeded()
    return cell
}
}
stefOCDP
  • 803
  • 2
  • 12
  • 20
  • thats great, i was writing you an ios7-compatible answer but see it isn't worth posting. I hadn't known about the autolayout improvements on cells in ios8, so now we don't need `heightForRowAtIndexPath` shenanigans. There is a useful comparison of iOS7 v iOS8 tableview cell resizing [here](https://www.captechconsulting.com/blogs/ios-8-tutorial-series-auto-sizing-table-cells) – foundry Apr 29 '15 at 09:01
  • +also this [amazingly detailed SO answer](http://stackoverflow.com/a/18746930/1375695) detailing both iOS7 and iOS8 patterns – foundry Apr 29 '15 at 09:09
  • thank you anyway. With this solution I get constraints errors in the console but the UI looks perfect. Hopefully I'll get rid of those soon. I will definitely look in to the linked SO answer. Thanks! – stefOCDP Apr 29 '15 at 18:36
1

I believe your problem comes from the estimatedRowHeight. You have to set it closer to what it's going to be in reality.

In your case with the current constraints, only the space between labels make 48. I had this problem too where not setting the estimatedRowHeight to a sensible number would make the tableview not to calculate anything good anymore.

Try to set it to 110 (3 x 20 for each label + 48 between them).

pteofil
  • 4,133
  • 17
  • 27
  • Thanks. I tried it, but it didn't work. I also set in a test case the height via heightForRowAtIndexPath. And the row height is about 600. So I tried to set the estimateRowHeight to 600. But it sill doesn't show correctly. – stefOCDP Apr 28 '15 at 20:08
  • I added a GitHub link where you can download the project – stefOCDP Apr 28 '15 at 20:30