Self-sizing Custom Table View Cells

A common challenge during app development is dynamic variable heights for your custom cells in a UITableView. In this post we will cover in a simple way how to make your cells size themselves according to the amount of text in them. For this example we shall create a table with generic posts layout, with each cell having a picture and name of user and some dummy text by the user underneath it – which will be of varying lengths. Here is the result.

Creating a self-sizing cell can be summarized in the following way

  1. Create cell subviews with proper constraints. Specifically, creating the resizing label with its edges constrained to the edges of the cell, and no height specified.
  2. Set tableview rowHeight as .automaticDimension, and any rough estimatedRowHeight value.
  3. That’s all! It’s that simple. There’s no third step.

Creating the cell

Assuming you already have a working project, start off by creating a new file in your project. Choose Cocoa Touch class, and give the name CommentCell, subclassing UITableViewCell. Make sure CreateXIB file option is checked.

You will get two files, a swift file and an xib file. Open the swift file and remove the generated code.

As shown in the screenshot, each cell will have 3 subviews.

  1. User image view
  2. User name label
  3. Text label

Let us now create these in the swift cell file.

import UIKit
class CommentCell: UITableViewCell {
    @IBOutlet var nameLbl: UILabel!
    @IBOutlet var textLbl: UILabel!
    @IBOutlet var userImg: UIImageView!
}

Add the following to make our imageView rounded.

    override func layoutSubviews() {
        super.layoutSubviews()
        userImg.layer.masksToBounds = true
        userImg.layer.cornerRadius = 30.0   
    }

Now go to the XIB file. In the identity inspector, set its reuse identifier as commentcell.

Now we shall create the subviews in xib and connect them to the outlets. This is the most important so I will go over this in detail.

The user image view

First, create a UIImageView and align it on the top left corner of the cell contentView. We need it fixed on to-left with a fixed size, so add necessary constraints, as shown below.

Now, right click on commentcell, and you will see outlets for all the three views we created in the swift file. Connect the userImg outlet to the UIImageView we just created in XIB, by dragging your cursor from the circle to the view.

The label for the name

Create a UILabel next to the userImg view as shown below and set the constraints shown.

Again, we need to connect this to the view outlet. Right click on cell and connect outlet to nameLbl to this label that you just created.

The text label

Create a third label, exactly below the nameLbl. We will position this to right of userImg and below nameLbl. The right edge and bottom edge will be constrained to right and bottom of the cell. No height will be specified. This will cause the cell’s height to grow with the label’s height.

Go to identity inspector and change its number of lines property to zero. This will cause the label to grow along with the text.

Once again, right click on cell and connect outlet for textLbl to this view.

Create the ViewController

Create a new file, name it MyTableViewController.

Set its rowHeight and estimatedRowHeightValues and register the custom cell that you created.

import UIKit
class MyTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.rowHeight = UITableView.automaticDimension
        self.tableView.estimatedRowHeight = 50.0
        self.tableView.register(UINib.init(nibName: "CommentCell", bundle: nil), forCellReuseIdentifier: "commentcell")
    }
}

Complete!

You’re done! Add some dummy data and test it.

let usernames = ["User1","User2","User3","User4","User5","User6","User7"]
let comments = ["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. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.","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. Excepteur sint occaecat cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum."]

TableView data source and delegate methods:

override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
   return comments.count
}
    
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
   let cell = tableView.dequeueReusableCell(withIdentifier: "commentcell") as! CommentCell
        
   cell.userImg.image = UIImage.init(named: "user1")
   cell.nameLbl.text = usernames[indexPath.row]
   cell.textLbl.text = comments[indexPath.row]
        
   return cell
}

Run the app and open the newly created MyTableViewController. You should be able to see cells with different sizes according to the content.


Also published on Medium.

By |2019-04-14T12:24:03+00:00April 14th, 2019|Categories: iOS Tutorials|Tags: |0 Comments

Leave A Comment