Automatically increase the static height of a table cell to match the height of the label content

Here is a low quality mockup of my cell layout:

mockup

The starting height of the static cell (set in the storyboard) is 80. There are two views inside this cell. The bottom view has a height of 40. The top view has layout constraints to align to the top and vertically align to the bottom.

Inside the top view is a label (blue) and a button (yellow)

The label also has constraints for alignment to the top of the view and alignment at the bottom of the view. The idea behind this layout and constraints is that if I increase the cell height to 100, for example, the height of the bottom image stays at 40, and the top view and label height expand to 60.

My label has word wrap per line and line count of 0. What I now want is to automatically resize the cell to get the full content of the label when there are multiple lines. How can i do this?

I tried:

self.tableView.rowHeight = UITableViewAutomaticDimension;
self.tableView.estimatedRowHeight = 80.0;

      

This does not work. The cell height always remains independent of the number of rows in UILabel

.

I've also tried:

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

      

With the same result as my first approach.

The more complicated way I tried was this:

override func tableView(_ tableView: UITableView, heightForRowAt indexPath: IndexPath) -> CGFloat {
    let heightLabel = self.heightForView(text: self.lblTitle.text!, font: UIFont(name: "Helvetica Neue", size: 18)!, width: self.lblTime.width);
    let heightView = (heightLabel + (80.0 / 2));

    print("title label height \(heightLabel)");
    print("title view height \(heightView)");

    if (heightView > 80.0) {
        return heightView;
    }

    return 80.0;
}

func heightForView(text: String, font: UIFont, width: CGFloat) -> CGFloat {
    let label: UILabel = UILabel(frame: CGRect(x: 0, y: 0, width: width, height: CGFloat.greatestFiniteMagnitude));
    label.numberOfLines = 0;
    label.lineBreakMode = .byWordWrapping;
    label.font = font;
    label.text = text;
    label.sizeToFit();

    return label.frame.height;
}

      

output:

title label height 42.5
title view height 82.5

      

But that also doesn't work as no other lines are displayed, only the first line of the label.

How can I get this to work?

EDIT

My guess is that the label height approach will work when I know the label width. But how am I supposed to know this?

+3


source to share


1 answer


From personal experience, getting UITableCells to grow properly is one of the most frustrating things about iOS. Typically, the biggest question is constraints. If they are not perfect, then the cell will not grow.

The key is to be able to draw a straight line from the top of the cell content view to the bottom of the content. so from your example the constants should look something like this.

topView.top == contentView.top
label.top == topView.top
label.bottom == topView.bottom
topView.bottom == bottomView.top
bottomView.height == 40
bottomView.bottom == contentView.bottom

      

Without this direct layout cannot determine the correct height for the label to display all of the content.



So, a fairly simple version of what you're looking for in the new sample project:

class ViewController: UITableViewController {
    @IBOutlet weak var label: UILabel!

    override func viewDidLoad() {
        super.viewDidLoad()

        self.tableView.rowHeight = UITableViewAutomaticDimension
        self.tableView.estimatedRowHeight = 80.0

        label.text = "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."
    }

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

      

In the same layout: Cell table layout

Results on the next display in the simulator. Displaying results

+5


source







All Articles