1

Long story short, iOS8 has a bug with UITableViewAutomaticDimension

So, you can't just call your tableView.rowHeight = UITableViewAutomaticDimension followed by the estimatedRowHeight because when reloading data someway through, you end up getting very jumpy, weird looking scrolling.

The way to mitigate this is apparently to return what the height of the cell is in func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat

Since you can't call cellForRowatIndexPath: in heightForRowAtIndexPath:, I basically copied my cellForRowAtIndexPath into the other method and changed it up for height. I can't seem to get it working though because my UILabel (the one with dynamic height in the cell), conforms to one line and just truncates instead of going on for x lines until all the content is displayed.

Note, postBody is the text that has a dynamic height.

My cellForRowAtIndexPath:

func tableView(tableView: UITableView, cellForRowAtIndexPath indexPath: NSIndexPath) -> UITableViewCell {
    var cell: UITableViewCell = self.feed.dequeueReusableCellWithIdentifier("post") as UITableViewCell

    var userName = cell.viewWithTag(1)! as UILabel
    var timestamp = cell.viewWithTag(2)! as UILabel
    var postBody = cell.viewWithTag(5)! as UILabel

    var post = self.posts[indexPath.row]

    userName.text = post.name
    timestamp.text = post.timestamp
    postBody.text = post.body

    return cell
}

my heightForRowAtIndexPath:

func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {

    var cell: UITableViewCell = self.feed.dequeueReusableCellWithIdentifier("post") as UITableViewCell

    var userName = cell.viewWithTag(1)! as UILabel
    var timestamp = cell.viewWithTag(2)! as UILabel
    var postBody = cell.viewWithTag(5)! as UILabel

    var post = self.posts[indexPath.row]

    userName.text = post.name
    timestamp.text = post.timestamp
    postBody.text = post.body

    cell.setNeedsLayout()
    cell.layoutIfNeeded()

    return cell.contentView.systemLayoutSizeFittingSize(UILayoutFittingCompressedSize).height
}

Why doesn't it work? With the UITableViewAutomaticDimension I got it working and conforming to the constraints I put through auto-layout, but can't get it here.

David
  • 7,028
  • 10
  • 48
  • 95

1 Answers1

0
  1. The jumpy scrolling you describe isn't a bug - it happens because your estimated height isn't close enough to your actual height.
  2. Don't dequeue a cell in your heightForRowAtIndexPath method. Basically, you're dequeueing a cell which will never be displayed since you're using it for height calculation.

You have a few options:

  • Improve your estimated height prediction.
  • In heightForRowAtIndexPath, you can use auto-layout to calculate your actual height by creating a cell instance that isn't dequeued from the table view. You can do this by:
    • creating your cells programmatically,
    • creating your cells in a .xib,
    • copying of your entire view controller and extract one cell from it programmatically
    • copying your cell in the storyboard and then extracting it via a property
Community
  • 1
  • 1
Aaron Brager
  • 65,323
  • 19
  • 161
  • 287
  • It's a bug that's been documented a few times on Stackoverflow and also I've tested estimated height from 0 up to twice as much as what the height ends up being, jumping all around. – David Jan 31 '15 at 03:16
  • Note that the algorithm can keep reusing the same dummy cell again and again each time it's called. Or 2-3 different dummies can be pre-created and one picked based on which cell layout scenario is being processed. – Hot Licks Jan 31 '15 at 03:31
  • I'm trying to create a cell that isn't dequeued with: `var cell = UITableViewCell(style: .Default, reuseIdentifier: "post")`, but then when I try to get views by tag like above, I get nil. How do I have auto-layout take over once the cell is made programmatically? – David Jan 31 '15 at 03:42
  • @david Your cell is made in a storyboard so you have to use one of the approaches I listed above, or create your cell programmatically. – Aaron Brager Jan 31 '15 at 08:24
  • It seems like what is being done in the link you posted 'extracting it via a property' is overkill for this. Can't I just take the Cell, and control drag it as a IBOutlet into my ViewController. Then, I'll have reference to it. From there, how can I use "auto-layout to calculate your actual height"? – David Jan 31 '15 at 09:50