TableView의 Cell의 크기(높이)가 Cell 내부 콘텐츠의 크기에 따라 동적으로 조정되도록 구현해보자
초기 화면에는 Feed의 내용(Caption으로 지칭)이 길어지면 해당 내용이 잘리게 되고 Feed(TableView Cell)의 높이 자체도 고정된 값으로 모든 Cell이 값은 높이를 가지게 된다.
이를 수정하여 사진의 높이, Caption의 길이에 맞게 Cell의 크기가 유동적으로 변하도록 구현하여 목표 화면처럼 UI를 구성하도록 하는 것이 목표이다.
기존에 Cell의 높이를 위해 사용했던 heightForRowAt 함수를 없애고
TableView를 담고 있는 ViewController의 viewDidLoad()에
tableView.rowHeight = UITableView.automaticDimension
tableView.estimatedRowHeight = 500
위와 같은 코드를 넣어준다. automaticDimension으로 rowHeight를 주게 되면 tableView의 Cell 높이가 오토레이아웃으로 결정된 높이를 동적으로 가지게 된다. (Cell의 xib파일의 오토레이아웃을 잘 설정해주어야 정상적으로 동작한다. Cell 내부의 UIImage와 superView.Bottom 사이의 cosntraint를 없애고 Cell의 가장 하단에 위치한 “댓글 n개 모두 보기" Label에 하단 constraint를 주어 Cell의 크기가 오토레이아웃으로 결정될 수 있도록 수정하였다.)
estimatedRowHeight를 이용하여 default 높이를 500으로 주었다.
이렇게 하면 이미지의 크기에 따라 Cell의 높이가 변하는 것을 확인 할 수 있다. 하지만 Label의 길이가 길어지면 해당 Label이 잘려서 보이는 상황(위에서 첨부한 초기 화면)은 유지되었다.
현재까지 FeedTableViewCell.xib의 상태는 위와 같다.
Caption이 담길 Label을 Caption 작성자 이름 Label 옆에 위치시킨 상태이며 넓이, 우측 간격에는 제약조건을 주지 않은 상태이다.
Label의 Lines가 1인 상태여서 한줄로 모든 내용이 표현되는 문제라 판단되어 해당 값을 0으로 설정하였으나 여전히 내가 원하는대로 Label이 여러줄로 표현되지 않고 한 줄로 잘려서 실행되었다.
Username이 사라지는 문제가 발생한다. Hugging Priority를 변경했기 때문에 priority가 낮은 쪽의 constriant가 무용지물이 되면서 UI가 깨진 것이다.
현재 발생한 문제는 Caption Label의 Width를 300인 고정값으로 주었기 때문에 발생한다.
그렇다면, 사용중인 기기의 스크린 넓이에 맞게 Caption Label의 Width를 설정하면 Label이 알맞은 크기를 가질 수 있을거라고 추측 할 수 있다.
⇒ 3번 해결 방안으로 연결
2번 코드를 추가한다. (⚠️ 위치 중요! : viewDidLoad에 추가하게 되면 captionWriterNameLabel의 넓이가 새롭게 지정되기 전(setData함수 실행 전)에 값을 계산하게 되기 때문에 정상적으로 작동하지 않는다. )
아래와 같이 코드를 구성
class FeedTableViewCell: UITableViewCell {
static let identifier = "FeedTableViewCell"
weak var delegate: FeedTableViewCellDelegate?
@IBOutlet weak var profileImageView: UIImageView!
@IBOutlet weak var profileNameLabel: UILabel!
@IBOutlet weak var feedImageView: UIImageView!
@IBOutlet weak var likeButton: UIButton!
@IBOutlet weak var likeCountLabel: UILabel!
@IBOutlet weak var captionWriterNameLabel: UILabel!
@IBOutlet weak var captionLabel: UILabel!
@IBOutlet weak var commentCountButton: UIButton!
// CaptionLabel Width constraint 연결
@IBOutlet weak var captionLabelWidth: NSLayoutConstraint!
//MARK: - Lifecycle
override func awakeFromNib() {
super.awakeFromNib()
}
//MARK: - Helpers
func setData(feedData: FeedDataModel) {
profileImageView.image = UIImage(named: feedData.profileImageName)
profileNameLabel.text = feedData.profileName
feedImageView.image = UIImage(named: feedData.feedImageName)
likeCountLabel.text = "좋아요 \(feedData.likeCount)개"
captionWriterNameLabel.text = feedData.profileName
captionLabel.text = feedData.caption
commentCountButton.setTitle("댓글 \(feedData.commentCount)개 모두 보기", for: .normal)
// 화면 크기에 따라 captionLabel의 Width 변경하도록 설정
captionLabelWidth.constant = UIScreen.main.bounds.width - (captionWriterNameLabel.intrinsicContentSize.width + 12 + 4 + 12)
}
}
captionLabelWidth.constant = UIScreen.main.bounds.width - (captionWriterNameLabel.intrinsicContentSize.width + 12 + 4 + 12)
위 코드를 setData함수에 추가했는데 이 코드의 의미는 다음과 같다.UIScreen.main.bounds.width : 현재 실행 중인 기기의 스크린 넓이값
captionWriterNameLabel.intrinsicContentSize.width : captionLabel 좌측에 위치한 caption 작성자 이름 Label의 넓이값
12 + 4 + 12 : 좌우 간격을 위한 값 (여백)
⇒ captionLabelWidth.constant 를 전체 스크린 넓이에서 caption 작성자 이름을 위한 Label의 넓이 만큼과 여백(간격)을 뺀 값으로 설정한 것이다. 이로 인해 기기가 달라지면 captionLabel의 width도 같이 달라져서 화면에 알맞게 들어가게 된다.
automaticDimention을 이용한 셀 동적 크기 설정이 안되는 경우를 만났다.
override func layoutSubviews() {
super.layoutSubviews()
contentView.frame = contentView.frame.inset(by: UIEdgeInsets(top: 0, left: 0, bottom: 0, right: 0))
}
위와 같은 layoutSubviews를 사용했을 때이다. 이 함수는 tableView cell간의 간격을 설정해주기 위해 사용하는 함수이다. 정확한 이유는 파악하지 못했지만 layoutSubviews함수를 사용하면 오토레이아웃에서 높이를 지정해주지 않은 요소들이 동적으로 커지지 못하는 결과를 확인했다.