| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 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 | 27 | 28 | 29 | 30 | 31 |
- 정보처리기사
- 정보처리기사 실기
- cocoapods
- programmers
- 프로그래머스
- UITableViewCell 동적높이
- CustomCode
- ios카메라유선연결
- 위클리챌린지
- Codable
- 2018 KAKAO BLIND RECRUITMENT
- usb카메라연결
- UITableViewCell dynamic height
- Pod
- IOS
- swift
- uikit
- parse
- AVFoundation
- avcapturesession
- ios외부디바이스연결
- Decodable
- 정보처리기사 실기 요약본
- Xcode
- JSONParser
- ios외부카메라연결
- UITableView
- ios 26
- Realm
- JSON
- Today
- Total
iOS 개발일기
[Swift] UITableView Cell 높이 동적 할당 방법 본문
이전 프로젝트들에서는 동적 높이를 할당할 때, 셀 내 모든 UI 요소들이 셀의 높이에 따라 다같이 변화하도록 설정된 셀만 사용했었으나
이벤 프로젝트에서는 셀은 기본적으로 동적인 높이를 가지고 UI 요소들 중 일부는 고정 크기, 일부는 동적 크기를 가지도록 하는 셀을 만들어야 했다.
그 중 하나의 셀을 예로 들자면,
- 제목 : UILabel (고정 크기)
- 내용 : UILabel (동적 크기)
- 버튼 : UIButton (고정 크기)
셀에는 총 3개의 요소를 가지고 있으며, 중앙의 내용을 표시하는 UILabel을 제외한 나머지 요소들은 고정된 크기를 가질 수 있도록 해야했다.

AutoLayout 기반으로 UI를 코드로 작성하면서 높이를 지정해주는 상황이 적다보니 생소한 부분이기도 했고
단순하게 셀의 높이를 `UITableView.automaticDimension` 으로 설정한 후에 셀 내에 타이틀과 버튼에 최소 크기를 명시해주기만 하면 속성에서 자동으로 최소 크기를 따라가지 않을까? 라는 생각에 타이틀과 버튼에 최소 크기를 지정한 결과...

셀 내에 Frame을 가지는 UI 요소의 높이가 `UITableView.automaticDimension`속성의 높이가 결정되는 대에 영향을 미치지 않는구나라는 것을 알게 되었다.
(`extimatedRowHeight`도 마찬가지로 테이블 뷰가 아직 높이를 계산하지 않은 셀의 높이를 추정하기 위해 사용되는 값일 뿐, 최소 값에 직접적인 영향을 미치진 않는다.)
이렇게 저렇게 해결 방법이 몇 가지 존재하였으나 서칭하던 중
func systemLayoutSizeFitting(
_ targetSize: CGSize,
withHorizontalFittingPriority horizontalFittingPriority: UILayoutPriority,
verticalFittingPriority: UILayoutPriority
) -> CGSize
라는 메서드의 존재에 대해 알게 되었는데 해당 메서드는 제약조건과 지정된 우선순위에 따라 최적의 View 크기를 반환하는 메서드라고 되어있다.
따라서, 제약조건이 설정되었을 때 즉 automaticDimension을 통해 셀의 크기가 결정되는 시점에 호출되는 메서드인 것이다.
이 메서드를 잘 이용하면 셀의 최소 크기도 지정할 수 있겠다 생각했다.
뷰 컨트롤러에서는 테이블 뷰 셀의 크기를 동적으로 할당될 수 있도록 지정해주고
func tableView(
_ tableView: UITableView,
cellForRowAt indexPath: IndexPath
) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(
withIdentifier: "DynamicCellID",
for: indexPath
) as! DynamicCell
cell.configure(datas[indexPath.row])
return cell
}
func tableView(
_ tableView: UITableView,
heightForRowAt indexPath: IndexPath
) -> CGFloat {
return UITableView.automaticDimension
}
셀 내에서는 동적으로 크기가 할당되는 시점에 자동으로 설정하려는 높이와 비교를 하여 더 큰 값의 높이를 리턴해주는 것이다.
class DynamicCell: UITableViewCell {
private let minHeight: CGFloat = UIScreen.main.bounds.height * 0.1
...
override func systemLayoutSizeFitting(
_ targetSize: CGSize,
withHorizontalFittingPriority horizontalFittingPriority: UILayoutPrioriy,
verticalFittingPriority: UILayoutPriority
) -> CGSize {
let size = super.systemLayoutSizeFitting(
targetSize,
withHorizontalFittingPriority: horizontalFittingPriority,
verticalFittingPriority: verticalFittingPriority
)
return CGSize(width: size.width, height: max(size.height, minHeight))
}
...
}
이렇게 코드를 작성하게 되면 셀은 제약조건이 설정되고 크기를 지정하려고 할 때 인터셉터를 하게 되어 셀의 최소 높이를 원하는 크기로 변경할 수 있다.
이 방법 외에도 여러 방법이 존재하였지만 7할은 StoryBoard 내에서 속성을 변경하는 방법이 대부분이 었던 것 같다.
아니면 `tableView(_:heightForRowAt:)` 메서드에서 레이아웃을 강제로 업데이트하여 크기를 계산하고 높이를 지정하거나 이와 비슷한 방식들이 많았던 것 같다.
외에도 UITableViewCell 내의 ContentView의 높이를 변경해주어 최소 크기를 변경하는 방법도 존재했었는데,
이 방법은 SnapKit을 사용하는 상황에서는 높이만 제약조건을 업데이트하게 되니 다른 제약조건들이 유지되지않고 한 방향으로 UI 요소들이 쏠리는 현상이 있어 모두 다시 지정해주어야하는 상황이 발생하기 때문에 이 방법을 선택하게 되었다.
이 방법은 명시적이지 않다는 의견도 있지만 현재 나의 환경에서는 가장 합리적인 선택인 것 같았고 추후 더 좋은 방법을 찾게 된다면 이 부분은 리팩토링을 거칠 예정이다.
'iOS > Swift' 카테고리의 다른 글
| [Swift] 앱 비활성화 시 앱 화면 가리기 (0) | 2025.08.04 |
|---|---|
| [Swift] UIKit 환경에서 Property Wrapper 사용하기 (0) | 2025.03.17 |
| [Swift] UICollectionView 'didSelectItemAt' 함수가 호출되지 않는 이유 (2) | 2023.12.07 |
| [Swift] JSONParser - JSONSerialization (0) | 2022.03.16 |
| [Swift] JSONParser - Decodable(2) (0) | 2022.03.15 |