Search code examples
swiftuitableviewuiimageviewconstraintscell

Set UIImageView height dynamically inside UITableViewCell according to cell height


I have a problem with an UITableViewCell that has UIImageView and a UILabel. All constraints are set programmatically, so that the constraints are adjusted so that the height of the cell varies dynamically with the height of the UILabel plus a certain padding, while the UIImageView must adapt to the height of the UITableViewCell. However, when I place the image, the height of the cell increases until it is that of the Image.

    contentView.addSubview(coverView)
    contentView.addSubview(indexUnitLabel)

    NSLayoutConstraint.activate([
        coverView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
        coverView.topAnchor.constraint(equalTo: contentView.topAnchor),
        coverView.bottomAnchor.constraint(equalTo: contentView.leadingAnchor),
        coverView.widthAnchor.constraint(equalToConstant: 68),

        titleLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: padding),
        titleLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -padding),
        titleLabel.leadingAnchor.constraint(equalTo: coverView.trailingAnchor, constant: padding),
        titleLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -padding)
    ])

Is there any way to set the constraints so that the height of the UIImageView adapts to the height of the cell dynamically?


Solution

  • I'm assuming you re-typed your code (instead of pasting the actual code), since you have coverView.bottomAnchor equal to contentView.leadingAnchor, as well as adding indexUnitLabel as a subview but then trying to constrain titleLabel...

    So, your constraints should look like this:

        NSLayoutConstraint.activate([
            coverView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor),
            coverView.topAnchor.constraint(equalTo: contentView.topAnchor),
            coverView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
            coverView.widthAnchor.constraint(equalToConstant: 68),
    
            indexUnitLabel.topAnchor.constraint(equalTo: contentView.topAnchor, constant: padding),
            indexUnitLabel.bottomAnchor.constraint(equalTo: contentView.bottomAnchor, constant: -padding),
            indexUnitLabel.leadingAnchor.constraint(equalTo: coverView.trailingAnchor, constant: padding),
            indexUnitLabel.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -padding)
        ])
    

    BUT... that doesn't give auto-layout enough information about what you want done with the height of the cell.

    You say you want the label height (plus padding) to determine the height of the cell, so add this line:

    indexUnitLabel.setContentHuggingPriority(.required, for: .vertical)
    

    That tells auto-layout to not expand the height of the label beyond its content.