AutoLayout — Hugging / Compression Resistance 이해하기
AutoLayout — Hugging / Compression Resistance 이해하기
1. 들어가며
AutoLayout은 iOS UI 개발의 근간이며, SwiftUI 이전 시대부터 유지되어 온 가장 중요한 레이아웃 시스템입니다.
그러나 많은 실무 개발자들이 제약 조건만 맞추는 데 집중하고 Hugging / Compression Resistance Priority(내부 우선순위 규칙)를 활용하지 않아
다음과 같은 문제가 계속 발생합니다.
- 화면이 특정 기기에서 깨짐
- 다국어(한국어/영어/중국어) 변환 시 UI 겹침
- Dynamic Type(큰 글씨) 적용 시 폭발
- Intrinsic Content Size 오작동
- UILabel이 예측 불가능하게 늘어남/줄어듦
이 문서는 AutoLayout 우선순위 개념과 Hugging / Compression Resistance를 실무에서 완전히 이해하고 적용할 수 있도록 정리했습니다.
2. AutoLayout이 레이아웃을 결정하는 방식
AutoLayout의 핵심 결정 요소는 다음 3가지입니다:
- Intrinsic Content Size
- Content Hugging Priority
- Content Compression Resistance Priority
여러 제약 조건이 “모호하거나 충돌하는 상황”일 때
이 우선순위가 어떤 뷰가 늘어나고 줄어드는지를 결정합니다.
3. Intrinsic Content Size란?
각 UI 컴포넌트가 “자연스럽게 차지하고 싶은 크기”입니다.
예:
- UILabel → 텍스트 길이
- UIButton → 텍스트 + 패딩
- UIImageView → 이미지 크기
Intrinsic이 없다면 Hugging/Compression은 의미가 없게 됩니다.
4. Content Hugging Priority
정의
“이 뷰는 늘어나고 싶지 않다”를 나타내는 우선순위입니다.
예:
두 개의 UILabel이 가로로 나란히 있을 때,
Hugging Priority가 낮은 UILabel이 늘어납니다.
기본값
- UILabel: 251
- UIView: 250
5. Content Compression Resistance Priority
정의
“이 뷰는 줄어들고 싶지 않다”를 나타내는 우선순위입니다.
예
두 UILabel이 공간이 부족한 경우,
Compression Resistance가 낮은 레이블이 줄어듭니다.
기본값
- UILabel: 751
- UIView: 750
6. Hugging vs Compression의 직관적 이해
| 상황 | 어떤 Prioritye가 영향? |
| 여유 공간이 있을 때 | Hugging(늘어나기 싫다) |
| 공간이 부족할 때 | Compression Resistance(줄어들기 싫다) |
7. 실무 예제 1 — “타이틀 + 설명 Label” 겹침 문제
[TitleLabel][DescriptionLabel------]
문제 상황:
- TitleLabel은 짧은 텍스트
- DescriptionLabel은 긴 텍스트
- 화면 너비 초과 시 DescriptionLabel이 잘려야 하는데 TitleLabel이 잘림
해결
titleLabel.setContentHuggingPriority(.required, for: .horizontal)
titleLabel.setContentCompressionResistancePriority(.required, for: .horizontal)
TitleLabel의 “지켜야 할 우선순위”를 높여 Title이 줄어드는 일을 방지.
8. 실무 예제 2 — UIButton과 UILabel의 충돌
문제:
- Button이 길어지면서 Label을 밀어버림
해결
UIButton을 더 잘 늘어나도록 하기:
button.setContentHuggingPriority(.defaultLow, for: .horizontal)
button.setContentCompressionResistancePriority(.defaultLow, for: .horizontal)
Label은 유지하고 버튼만 늘어나도록 한다.
9. 실무 예제 3 — 다국어 대응
영어: Settings
독일어: Einstellungen
Label이 길어져도 UI가 깨지지 않게 해야 한다.
해결
좌측 타이틀(Hugging 높음)
우측 설명(Hugging 낮음 → 늘어나기 쉬움)
10. 실무 예제 4 — Dynamic Type(큰 글씨 모드)
큰 글씨 모드에서는 UILabel의 Intrinsic Size가 매우 커지므로
Compression Resistance를 낮춘 Label이 먼저 줄어들어 균형이 맞는다.
11. StackView에서의 Hugging / Compression
많은 개발자가 StackView 내부에서는 Priority가 무시된다고 오해한다.
→ 절대 아니다.
StackView는 내부 뷰의 Hugging/Compression을 매우 중요하게 반영한다.
예:
- 수평 StackView
- 아이콘(ImageView) + 텍스트(Label)
텍스트가 길어지면 아이콘이 찌그러지지 않게 해야 한다.
imageView.setContentCompressionResistancePriority(.required, for: .horizontal)
12. UICollectionViewCell에서의 레이아웃 문제 해결
문제:
- 셀 안에서 UILabel 길이에 따라 오토레이아웃 깨짐
해결:
- ContentView와 내부 컴포넌트의 Hugging/Compression 조정
- preferredMaxLayoutWidth 설정
label.preferredMaxLayoutWidth = UIScreen.main.bounds.width - 40
13. AutoLayout 디버깅 방법
13.1 Runtime Constraints Log 보기
po view.constraintsAffectingLayout(for: .horizontal)
po view.constraintsAffectingLayout(for: .vertical)
13.2 Hugging/Compression 값 확인
po label.contentHuggingPriority(for: .horizontal).rawValue
13.3 UILabel이 잘릴 때 확인해야 할 옵션
label.lineBreakMode
label.numberOfLines
14. 체크리스트
- 레이블이 양옆에 있을 때 우선순위를 반드시 조정했는가?
- 다국어 지원을 고려했는가?
- Dynamic Type을 테스트했는가?
- StackView 내부 우선순위를 확인했는가?
- 이미지뷰가 찌그러지지 않도록 Compression을 높였는가?
- UIButton이 레이아웃을 밀어내지 않도록 설정했는가?
15. 결론
Hugging / Compression Resistance는 AutoLayout의 심장과도 같습니다.
단순히 제약 조건만 맞추는 대신, 어떤 컴포넌트가 늘어나야 하고, 어떤 컴포넌트가 줄어들지 말아야 하는지를 명확하게 정의하면
UI는 모든 디바이스, 모든 언어, 모든 상황에서 안정적으로 표시됩니다.