Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to create static cells with dynamic cell heights with Swift

I have looked at several tutorials that show how to set dynamic cell heights, but all of them only show it if you are using dynamic cells by setting the appropriate constraints and using UITableViewAutomaticDimension. However, I would like to do this for static cells.

I have a table view controller in my app that contains several cells that display a category with a disclosure indicator in which there is a title and then a description and the size of the description text varies. Thus, I would like the height of the cell to be dynamic per the size of the description text.

The reason why I am using static cells and not dynamic cells is because above the category cells I have a few cells with some designs that I could only get by using static cells and storyboarding.

I am using iOS9, Xcode 7.3 and Swift 2.2

UPDATE

Table View Controller Code

import UIKit

class CategoriesTableViewController: UITableViewController {

    override func viewDidLoad() {
        super.viewDidLoad()

        tableView.rowHeight = UITableViewAutomaticDimension
        tableView.estimatedRowHeight = 140
    }

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

    // MARK: - Table view data source

    override func numberOfSectionsInTableView(tableView: UITableView) -> Int {
        // #warning Incomplete implementation, return the number of sections
        return 1
    }

    override func tableView(tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
        // #warning Incomplete implementation, return the number of rows
        return 2
    }

}

UPDATE 2

Per accepted answer below I added the two methods below to my table view controller and removed the 2 lines I had in viewDidLoad(). This did it for me! Keep in mind that I had to make sure all the labels in each cell used a top, bottom, leading and trailing constraint. Also, the number of lines for each label must be set to 0.

override func tableView(tableView: UITableView, heightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}

override func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}
like image 984
Jace Avatar asked Aug 04 '16 23:08

Jace


4 Answers

UILabel:

Set numberOfLines = 0 via programmatically or set lines to zero in attributes inspector of the UILabel.

enter image description here

UITextView:

Let's select your text view and uncheck the scrolling enabled like as below image.

enter image description here

Add the below code to your view controller:

Swift 5:

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

func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableView.automaticDimension
}

Swift 2.2:

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

 func tableView(tableView: UITableView, estimatedHeightForRowAtIndexPath indexPath: NSIndexPath) -> CGFloat {
   return UITableViewAutomaticDimension
 }
like image 200
Rajamohan S Avatar answered Nov 15 '22 20:11

Rajamohan S


@Forge, add please to your topic
Swift 4 variant:

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

override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
    return UITableViewAutomaticDimension
}
like image 23
Vladislav Teterin Avatar answered Nov 15 '22 20:11

Vladislav Teterin


For Swift 3

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

 override func tableView(_ tableView: UITableView, estimatedHeightForRowAt indexPath: IndexPath) -> CGFloat {
   return UITableViewAutomaticDimension
 }
like image 23
kashlo Avatar answered Nov 15 '22 20:11

kashlo


All you have to do is set proper AutoLayout inside the cell, so the height increases based on the length of the description text. Then you need to set the following in your viewDidLoad

tableview.rowHeight = UITableViewAutomaticDimension
tableview.estimatedRowHeight = 44

Please note: you need to set the numberOfLines of UILabel to 0

like image 29
Mohammed Shakeer Avatar answered Nov 15 '22 21:11

Mohammed Shakeer