Self-Sizing Table View Cell in Xcode 9

14,515

Solution 1

I had the same problem and solved it with to lines of code:

class MyTableViewController: UITableViewController {
  override func viewDidLoad() {
    super.viewDidLoad()

    tableView.estimatedRowHeight = UITableViewAutomaticDimension
    tableView.rowHeight = UITableViewAutomaticDimension
  }

Maybe it is a bug in Xcode.

Update

New in Xcode 9 beta 3:

Interface Builder now supports setting the estimatedRowHeight of UITableView. This allows self-sizing table cells by setting the estimated height to a value other than zero, and is on by default. (17995201)

Solution 2

I had the same broken table view issue. Fix was just one click.

Go to your xib or storyboard scenes with table views, go to the size inspector, and you'll see the table view heights (even on dynamic table views) as 44, and sections will be 22. Just click "automatic" and boom, it will present as expected.

enter image description here

Note that I also specify the following in viewDidLoad of the UITableViewController subclass (layoutSubviews solves issues with the first load of a tableViewController not positioning correctly in relation to a non-translucent navBar).

   self.tableView.estimatedRowHeight = 180;
   self.tableView.rowHeight = UITableViewAutomaticDimension;
   self.tableView.separatorStyle = UITableViewCellSeparatorStyleNone;
  [self.tableView layoutSubviews];

Solution 3

For me, Safe Area was checked. Unchecking "Safe Area" did the work for me.

"Safe Area"

Solution 4

In addition to

tableView.estimatedRowHeight = UITableViewAutomaticDimension
tableView.rowHeight = UITableViewAutomaticDimension

you should set a height constraint for the contentView of the tabeleViewCell.

class CustomTableViewCell: UITableViewCell {
    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {
        super.init(style: style, reuseIdentifier: reuseIdentifier)

        let height: CGFloat = 200
        heightAnchor.constraint(equalToConstant: height).isActive = true
    }
}

Solution 5

I got the same issue and I read about it in many documentation, satisfying answer was something like this, You have to check both options in order to get proper height, because estimated height is needed for initial UI setup like scrollview bars and other such stuff.

Providing a nonnegative estimate of the height of rows can improve the performance of loading the table view. If the table contains variable height rows, it might be expensive to calculate all their heights when the table loads. Using estimation allows you to defer some of the cost of geometry calculation from load time to scrolling time. When you create a self-sizing table view cell, you need to set this property and use constraints to define the cell’s size. The default value is 0, which means there is no estimate. (Apple Documentation)>

see this image for storyboard

Also note that there is a bug in xCode 9, when you try to apply Lazy loading in automatic height calculation, it will scroll unexpectedly, so I'll recommend you to use programmatic way in this regard.

self.postTableView.estimatedRowHeight = 200;
self.postTableView.rowHeight = UITableViewAutomaticDimension;

something Like this. Thanks!

Share:
14,515

Related videos on Youtube

SRMR
Author by

SRMR

Updated on June 07, 2022

Comments

  • SRMR
    SRMR almost 2 years

    I have a UITableViewController where the cell's self sized correctly using Xcode 8 and Swift 3. Now that I'm using Xcode 9 and Swift 4, they aren't expanding and are just using the default height of 44.

    (I have about a sentence or two in each UITableViewCell)

    I was using this before:

    // MARK: - Table view delegate
    
    override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    
    override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
        return UITableViewAutomaticDimension
    }
    

    ... but was able to comment it out because per Updating Your App for iOS 11 said that the default would be self-sizing now:

    enter image description here

    I've tried playing around with changing the deployment target to iOS 11, playing around in Storyboard (but I'm using a Table View Cell style Basic so there is not much AutoLayout to be done), and I can't figure out what is going on.

    I have the UILabel title set to 0 Lines, and have Line Break Word Wrap, but still not getting anywhere close to getting the cell to expand based on the text content inside of it in Xcode 9. Any ideas?

    Thanks!

    Edit:

    Here's the options (that I don't have) for pinning since it is a Basic cell:

    enter image description here

    enter image description here

    enter image description here

    • EmilioPelaez
      EmilioPelaez almost 7 years
      If you want your cells to expand, the content has to be pinned with Auto Layout at least to the top and the bottom of your cell, are you doing that?
    • Robotic Cat
      Robotic Cat almost 7 years
      Xcode 9 and the iOS 11 SDK are still in beta so there will be bugs. If this is a bug in beta software then it should be reported to Apple.
    • SRMR
      SRMR almost 7 years
      @EmilioPelaez I added some images to my original question as to the lack of options I have, does that clarify? Thanks!
    • SRMR
      SRMR almost 7 years
      @RoboticCat right, I'll do that if I know it's a bug for sure, but was wondering if anyone knew that there was something specific I was missing or not you know?
    • Reinier Melian
      Reinier Melian almost 7 years
      its the content what you need to add constraints, not the cell itself, I think that will be the same constraints needed in iOS 10 XCode8 for automaticDimensionCells, did you adjust the content compression resistance priority and content hugging priority?
    • SRMR
      SRMR almost 7 years
      @ReinierMelian I have not adjusted that. Should I do that, and are you saying to do that on the Content View? I don't see the option for that on the Content View in the Storyboard, so I'm not sure if that's an option for me or if I'm just missing it.
    • Reinier Melian
      Reinier Melian almost 7 years
      I had been done this in iOS 10 Xcode 8, I don't have XCode 9 but in XCode 8 I put all the constraints inside the contentView and adjusting content compression resistance priorityand content hugging priority work just fine
    • SRMR
      SRMR almost 7 years
      @ReinierMelian do you see in my Storyboard screenshots that it doesn't look like I can do that on the Content View? Or am I missing something with that potentially?
    • Reinier Melian
      Reinier Melian almost 7 years
      @SRMR The contentView can't be touched, but you can put your label inside the contentView and set top bottom, left and right constraints and adjust the properties content compression resistance priority and content hugging priority must work
    • Reinier Melian
      Reinier Melian almost 7 years
      @SRMR now seeing your screenshot you don't have active autolayout at all, you are using autoresizing mask? this can be the source of your problem
    • Reinier Melian
      Reinier Melian almost 7 years
      @SRMR please let me know if you solve your problem
    • SRMR
      SRMR almost 7 years
      @ReinierMelian because it is a Basic cell type, I don't put a label inside the Content View because there already is a title label there by default, you know?
    • Reinier Melian
      Reinier Melian almost 7 years
      You can add a custom cell and add your label with the constraints as i said and set content compression resistance priority and content hugging priority? and let me know, without autolayout automatic dimensions for cells don´t work because tableView first run autolayout engine methods to make calculations of the needed height for cell
    • SRMR
      SRMR almost 7 years
      @ReinierMelian totally could do that, but I can't imagine that this would be something that would be unavailable with their default Basic and Subtitle cells right? Thanks for the help!
  • SRMR
    SRMR almost 7 years
    Hi! Yeah that is the same as what I put in my original question with func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension } and func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat { return UITableViewAutomaticDimension }
  • i89
    i89 over 6 years
    Setting estimatedRowHeight and rowHeight to UITableViewAutomaticDimension worked for me in Xcode 9 beta 6
  • Nininea
    Nininea over 6 years
    helpful answer ^^
  • PJ_Finnegan
    PJ_Finnegan over 6 years
    In Xcode Version 9.0.1 (9A1004), the IB settings were already to auto, but at the first draw the rows were compressed, the height being corrected at next redraws only. To fix this, I had to insert your code lines.
  • SAHM
    SAHM over 6 years
    Also, this does not seem to work in iOS 11 for a non-subclassed cell of type UITableViewCellStyleValue1 with a multiline detail label.
  • Mike Critchley
    Mike Critchley over 6 years
    It works in iOS10. Haven't tried it in iOS11 on a device. I'll check it out after I update my iOS (I never rush into those early updates lol). And all the cells I use are custom UITableViewCell subclasses loaded dynamically. I don't do any table view UI in IB.
  • Wyatt Page
    Wyatt Page about 6 years
    I spent almost half a day on this before I found your answer. First load of cell would never dynamically size height, but subsequent loads or even changing with accessibility inspector rendered correctly. Thank you!