I have a table view with a custom cell that will display comments from users. In the view conrtoller where the table view is located, I make a network call to fetch the comments and the related images for each comment, I then calculate the aspect ratio of the images and pass it along with the comment to the custom cell in cellForRowAt method.
I pass the above information by calling a method in the custom cell which also sets the constraints for both the textView and the ImageView.
My goal is to have the textView start from top and leading with 5 buffer and be trailing the ImageView's leading with 5 buffer as well. The ImageView will have a fixed height of 70 and calculate the width based on the passed aspect ratio.
I want the cell to auto expand depending on the textView length while also at the same time have the ImageView maintain 5 points from the bottom in case the textView is short.
Below are the constraints I call in init of the custom cell:
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .red
contentView.addSubview(commentTextView)
contentView.addSubview(relatedImage)
NSLayoutConstraint.activate([
commentTextView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
commentTextView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
commentTextView.trailingAnchor.constraint(equalTo: relatedImage.leadingAnchor, constant: -5),
commentTextView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
relatedImage.heightAnchor.constraint(equalToConstant: 70),
relatedImage.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
relatedImage.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
relatedImage.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, constant: -5),
])
aspectConstraint = relatedImage.widthAnchor.constraint(equalTo: self.relatedImage.heightAnchor, multiplier: 1)
}
Below is a function in the custom cell that I call from cellForRowAt to pass the UIImages along with the aspect ratio:
func setUpImage(aspectRatio: Double, image: UIImage) {
relatedImage.image = image
aspectConstraint.isActive = false
relatedImage.widthAnchor.constraint(equalTo: self.relatedImage.heightAnchor, multiplier: aspectRatio).isActive = true
contentView.layoutIfNeeded()
}
I also have the textView scroll disabled and the tableView heightForRowAt set to auto dimensions and estimated row height set at 80.
Problem I am facing is I am unable to satisfy the below constraints at the same time:
1- commentTextView must autoresize the tableview cell depending on its content.
2- ImageView must have a height of 70 and be 5 points from top.
3- ImageView must at least maintain 5 points from the bottom of the cell meaning if the commentTextView is short I don't want the cell to shrink to the point of clipping the imageView.
Below is the full custom cell class if that helps
class CommentCell: UITableViewCell {
let usernameLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 15, weight: .semibold)
label.textColor = .white
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let timeAgoLabel: UILabel = {
let label = UILabel()
label.font = UIFont.systemFont(ofSize: 12, weight: .regular)
label.textColor = .white
label.translatesAutoresizingMaskIntoConstraints = false
return label
}()
let commentTextView: UITextView = {
let textView = UITextView()
textView.translatesAutoresizingMaskIntoConstraints = false
textView.textColor = .white
textView.backgroundColor = .red
textView.text = "Send a comment"
textView.isEditable = false
textView.isScrollEnabled = false
textView.alpha = 1
textView.keyboardDismissMode = .none
textView.returnKeyType = .send
textView.isHidden = false
textView.layer.borderColor = UIColor.yellow.cgColor
textView.layer.borderWidth = 1
textView.contentMode = .left
return textView
}()
private let relatedImage: UIImageView = {
let vw = UIImageView()
vw.contentMode = .scaleAspectFit
vw.translatesAutoresizingMaskIntoConstraints = false
vw.isUserInteractionEnabled = true
vw.clipsToBounds = true
vw.layer.masksToBounds = true
return vw
}()
var aspectConstraint: NSLayoutConstraint!
override init(style: UITableViewCell.CellStyle, reuseIdentifier: String?) {
super.init(style: style, reuseIdentifier: reuseIdentifier)
contentView.backgroundColor = .red
contentView.addSubview(commentTextView)
contentView.addSubview(relatedImage)
NSLayoutConstraint.activate([
commentTextView.leadingAnchor.constraint(equalTo: contentView.leadingAnchor, constant: 10),
commentTextView.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
commentTextView.trailingAnchor.constraint(equalTo: relatedImage.leadingAnchor, constant: -5),
commentTextView.bottomAnchor.constraint(equalTo: contentView.bottomAnchor),
relatedImage.heightAnchor.constraint(equalToConstant: 70),
relatedImage.trailingAnchor.constraint(equalTo: contentView.trailingAnchor, constant: -10),
relatedImage.topAnchor.constraint(equalTo: contentView.topAnchor, constant: 5),
relatedImage.bottomAnchor.constraint(lessThanOrEqualTo: contentView.bottomAnchor, constant: -5),
])
aspectConstraint = relatedImage.widthAnchor.constraint(equalTo: self.relatedImage.heightAnchor, multiplier: 1)
}
required init?(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
func setUpImage(aspectRatio: Double, image: UIImage) {
relatedImage.image = image
aspectConstraint.isActive = false
relatedImage.widthAnchor.constraint(equalTo: self.relatedImage.heightAnchor, multiplier: aspectRatio).isActive = true
contentView.layoutIfNeeded()
}
}