UIStackView는 여러 개의 서브뷰(subview)를 일정한 축(axis)으로 자동 배치하고 관리해주는 UIKit 컴포넌트이다.
이때 각 서브뷰의 크기를 결정하는 중요한 기준은 두 가지 우선순위(priority)이다.
이 두 속성은 뷰의 크기 변화가 발생할 때, 각각의 뷰가 어떻게 공간을 유지하거나 포기할지를 결정하는 중요한 기준이다.
UIKit에서 뷰의 크기는 다음 두 가지 기준을 기반으로 결정된다.
.required, 높음)까지 설정 가능.즉, UIStackView가 너무 좁아질 때 뷰가 줄어드는 순서를 정하는 기준이 바로 Content Compression Resistance Priority이다.
수평(.horizontal)으로 배열된 UIStackView 안에 두 개의 UILabel(왼쪽 레이블과 오른쪽 레이블)이 존재한다고 가정하자.
leftLabel)의 텍스트는 "Author", "Released", "Pages" 등 고정적이며, 콘텐츠 크기가 변경될 가능성은 낮다.rightLabel)은 이름, 날짜, 페이지 수 등 콘텐츠의 길이가 달라지고 길어질 수 있다.이때 원하는 레이아웃 조건은 다음과 같다:
// 두 개의 레이블 생성
let leftLabel = UILabel()
leftLabel.text = "Author"
leftLabel.font = .systemFont(ofSize: 16, weight: .bold)
let rightLabel = UILabel()
rightLabel.text = "J.K. Rowling"
rightLabel.font = .systemFont(ofSize: 16)
// StackView 설정
let horizontalStackView = UIStackView(arrangedSubviews: [leftLabel, rightLabel])
horizontalStackView.axis = .horizontal
horizontalStackView.alignment = .fill
horizontalStackView.distribution = .fill
horizontalStackView.spacing = 8
// 왼쪽 레이블 설정
leftLabel.setContentHuggingPriority(.required, for: .horizontal) // 추가 공간 확보 금지
leftLabel.setContentCompressionResistancePriority(.required, for: .horizontal) // 절대 축소 금지
// 오른쪽 레이블 설정 (기본값 유지)
rightLabel.setContentHuggingPriority(.defaultLow, for: .horizontal) // 추가 공간 확보 허용
rightLabel.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) // 필요 시 축소 허용
| 레이블 | Content Hugging Priority | Content Compression Resistance Priority | 최종 동작 |
|---|---|---|---|
왼쪽 레이블 (leftLabel) | .required (높음) | .required (높음) | 크기 고정 (절대 늘어나거나 축소되지 않음) |
오른쪽 레이블 (rightLabel) | .defaultLow (낮음) | .defaultLow (낮음) | 공간이 많으면 늘어나고, 공간이 부족하면 축소됨 |
즉, 왼쪽 레이블은 언제나 고정된 너비를 유지하고, 오른쪽 레이블이 남은 공간에 따라 확장 또는 축소되는 결과를 얻을 수 있다.
| Priority | 의미 (역할) | 설정 방법 |
|---|---|---|
| Content Hugging Priority | 추가 공간이 생겼을 때 콘텐츠 크기 이상으로 늘어나는 것을 방지 | 높은 값을 설정하면 늘어나지 않음 |
| Content Compression Resistance Priority | 공간이 부족할 때 콘텐츠 크기 이하로 줄어드는 것을 방지 | 높은 값을 설정하면 축소되지 않음 |
두 Priority를 모두 높게 설정하는 경우, 레이블은 절대로 자신의 크기보다 늘어나거나 축소되지 않는다.
다음 두 줄이 핵심 코드이다:
leftLabel.setContentHuggingPriority(.required, for: .horizontal)
leftLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
이 두 줄만으로 왼쪽 레이블이 자신의 크기를 엄격히 유지하면서, 오른쪽 레이블이 남은 공간을 유연하게 활용할 수 있는 원하는 레이아웃을 구현할 수 있다.