Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to have multiple cell sizes in a dynamic tableView in swift?

I want to have cells with different sizes in a tableView but all after build and running the app I see that all cells have same size and the bigger cell gets cropped and its content become incomplete. I set sizes in attribute inspector.

this is an screenshot

like image 807
SinaSB Avatar asked Apr 23 '17 12:04

SinaSB


2 Answers

it is as simple as implementing:

func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    return CGFloat(#your desired size#)
}

just use a switch/case in this function and work with indexPath.row. You can also use UITableViewAutomaticDimension for automatic sizing

EDIT:

According to the title, description of this question, and the picture provided I guessed 3 possible situations and tried to cover all in my short answer above. But as Rikh thought it was not the situation, I am going to clear things up.

Remember that for dynamic rows you must fix all the views in their place in autolayout, meaning you have to set constraints from top of the scene to the bottom and left to the right. Possible Situations are:

Situation 1: You have 2 different cells in your table and you know their sizes (first row is type1 and other cells are type2).

In this situation you just need to add an if clause or switch/case in the function I mentioned like this (Imagining that first row is 88 point and the rest are 44 point):

return indexPath.section == 0 ? CGFloat(88.0) : CGFloat(44.0)

Situation 2: Your first row is fixed size and the rest are dynamic.

After you set correct constraints on your cells, in viewDidLoad add tableView.estimatedRowHeight = CGFloat(44.0) in which the estimatedRowHeight is the minimum possible height for your cells. Then you can write your code like this:

return indexPath.section == 0 ? CGFloat(88.0) : UITableViewAutomaticDimension

Situation 3: The height of your rows are all dynamic and you want all of them to expand by themselves. In this situation you do not need the function I mentioned at all. Actually if you have it in your code you must remove it. In this situation go on and add this code to viewDidLoad of your code (Imagining minimum possible height of your cells is 44 point):

tableView.rowHeight = UITableViewAutomaticDimension
tableView.estimatedRowHeight = CGFloat(44.0)

Again remember that it is really important to set all of your constraints correctly for this to work. An example: I guess "detail" label is the one that will make your row's height grow and title is fixed size, so these are the constraints you need on your "detail" label: set its height to greater than equal (>=) 21, set it to align vertically in middle of superview (by setting "Vertically in Container" constraint in your storyboard), set horizontal space to "title" label, set trailing space to superview, set number of lines to 0 which makes it expand infinitely, and finally set the line break attribute to "word wrap". In this situation your title must have specific width constraint or you'll get an error.

P.S.: Actually now that I am writing this I can imagine another situation in which your "title" label's width is also dynamic. This will make your tableView really ugly but if this is your situation, you need to set "content hugging" and "Content Compression" on your labels, which is described Here (CHCR)

like image 138
Arash Tabrizian Avatar answered Sep 21 '22 10:09

Arash Tabrizian


Define auto layout constraints for your prototype cell.

Specify the estimatedRowHeight of your table view

Set the rowHeight of your table view to UITableViewAutomaticDimension

Example

tableView.estimatedRowHeight = 44.0
tableView.rowHeight = UITableViewAutomaticDimension

If you are using Autolayout everything will work as expected.

Sample demo you will get here.

https://www.dropbox.com/s/ug9xu0yfcua902o/SelfSizingDemo.zip?dl=0

like image 31
Jitendra Avatar answered Sep 21 '22 10:09

Jitendra