guy
guy

Reputation: 619

Auto size UITableViewCell with two UILabels

I'm trying to use auto layout to size a UITableViewCell to always fit its content.

Each cell contains two labels topLabel and bottomLabel, which are vertically stacked. I want both labels to wrap and show all of their text.

I'm using iOS8.

Here's my code

class MyTableViewCell: UITableViewCell {
    @IBOutlet var topLabel: UILabel!
    @IBOutlet var bottomLabel: UILabel!

    override init(style: UITableViewCellStyle, reuseIdentifier: String?) {

        super.init(style: style, reuseIdentifier: reuseIdentifier)

        topLabel = UILabel()
        topLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
        topLabel.numberOfLines = 0
        contentView.addSubview(topLabel)

        bottomLabel = UILabel()
        bottomLabel.setTranslatesAutoresizingMaskIntoConstraints(false)
        bottomLabel.numberOfLines = 0
        contentView.addSubview(bottomLabel)

        let viewDictionary = ["topLabel": topLabel, "bottomLabel": bottomLabel]
        var constraints = [NSLayoutConstraint]()

        contentView.addConstraints(
            NSLayoutConstraint.constraintsWithVisualFormat(
                "H:|-[topLabel]-|",
                options:NSLayoutFormatOptions(0),
                metrics: nil,
                views: viewDictionary))

        contentView.addConstraints(
            NSLayoutConstraint.constraintsWithVisualFormat(
                "H:|-[bottomLabel]-|",
                options:NSLayoutFormatOptions(0),
                metrics: nil,
                views: viewDictionary))

        contentView.addConstraints(
            NSLayoutConstraint.constraintsWithVisualFormat(
                "V:|-[topLabel]-[bottomLabel]-|",
                options:NSLayoutFormatOptions(0),
                metrics: nil,
                views: viewDictionary))

    }

    required init(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

class MyTableViewController: UITableViewController, UITableViewDataSource {

    override func tableView(tableView: UITableView,
        numberOfRowsInSection section: Int) -> Int {

        return 5;
    }

    override func viewDidLoad() {
        tableView.rowHeight = UITableViewAutomaticDimension
        super.viewDidLoad()
    }

    override func tableView(
        tableView: UITableView, 
        cellForRowAtIndexPath indexPath: NSIndexPath) ->
        UITableViewCell {

        let cell = MyTableViewCell(
            style: UITableViewCellStyle.Default, 
            reuseIdentifier: nil)

        cell.topLabel.text = "1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26"
        cell.bottomLabel.text = "A B C D E F G H I J K L M N O P Q R S T U V W X Y Z"

        return cell
    }
}

However, only the top label's text wraps. The result is

enter image description here

I'm not sure whether I'm messing up my constraints, or if there's another property I'm supposed to set, or whether this is just not possible. Any help would be greatly appreciated.

Upvotes: 0

Views: 379

Answers (2)

gabbler
gabbler

Reputation: 13766

Adding this line in your cellForRowAtIndexPath seems to be able to fix the problem.

cell.layoutIfNeeded()

Upvotes: 2

Syed Ali Salman
Syed Ali Salman

Reputation: 2915

Firstly you should use table view delegate heightForRowAtIndexPath to return height of cell for that row.Secondly please set the numbers of rows of your labels within cell to zero. if you are having confirm constraints and returning right height of cell then you'll get exactly what are you wanting.

Thanks

Upvotes: 0

Related Questions