개발/iOS

AutoLayout — Hugging / Compression Resistance 이해하기

까칠코더 2025. 11. 14. 16:27
반응형

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가지입니다:

  1. Intrinsic Content Size
  2. Content Hugging Priority
  3. 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는 모든 디바이스, 모든 언어, 모든 상황에서 안정적으로 표시됩니다.

반응형