はじめに
UITableViewCell にセットする画像のアスペクト比が固定ではない場合、セルの高さの決め方を工夫する必要があります。今回はその方法の一つとして、 AutoLayout を用いた解決策を示します。
解決策
final class CustomTableViewCell: UITableViewCell {
@IBOutlet private weak var mainImageView: UIImageView!
private var aspectConstraint: NSLayoutConstraint? {
didSet {
if let value = oldValue {
mainImageView.removeConstraint(value)
}
if let constraint = aspectConstraint {
mainImageView.addConstraint(constraint)
}
}
}
func prepare(image: UIImage) {
setImage(image)
}
private func setImage(_ image: UIImage) {
let aspect = image.size.width / image.size.height
let constraint = NSLayoutConstraint(
item: mainImageView as Any,
attribute: .width,
relatedBy: .equal,
toItem: mainImageView,
attribute: .height,
multiplier: aspect,
constant: 0.0
)
constraint.priority = UILayoutPriority(rawValue: 999)
aspectConstraint = constraint
mainImageView.image = image
}
}
aspectConstraint: NSLayoutConstraint?
ではセルの再利用を考慮して制約の削除も行っています。また、セルに対して複数回画像がセットされる可能性がある場合(セルのイニシャライズが行われてから破棄されるまでの間に複数回 setImage()
が呼ばれる場合)にも対応します。
実際に制約を作成して UIImageView に適応するのが setImage()
になります。 priority
に関しては、構築している UI に応じて臨機応変に設定してください。