UIStackView 내에서 Hugging/Compression Resistance 사용하기

Evan·2025년 4월 2일

UIStackView는 여러 개의 서브뷰(subview)를 일정한 축(axis)으로 자동 배치하고 관리해주는 UIKit 컴포넌트이다.

이때 각 서브뷰의 크기를 결정하는 중요한 기준은 두 가지 우선순위(priority)이다.

  • Content Hugging Priority: 콘텐츠 크기보다 더 커지지 않으려는 우선순위.
  • Content Compression Resistance Priority: 콘텐츠 크기보다 더 작아지지 않으려는 우선순위.

이 두 속성은 뷰의 크기 변화가 발생할 때, 각각의 뷰가 어떻게 공간을 유지하거나 포기할지를 결정하는 중요한 기준이다.



1. Content Hugging Priority의 개념


UIKit에서 뷰의 크기는 다음 두 가지 기준을 기반으로 결정된다.

Intrinsic Content Size

  • 콘텐츠가 본래 가지고 있는 자연스러운 크기.
  • 예시: UILabel이 텍스트를 모두 보여줄 수 있는 최소 크기.

Content Hugging Priority

  • 자신의 콘텐츠 크기를 유지하려는 경향을 나타내는 우선순위.
  • 1(낮음)에서 1000(.required, 높음)까지 설정 가능.
  • 높은 우선순위일수록 여유 공간이 있을 때도 콘텐츠 크기 이상으로 늘어나지 않는다.



2. Content Compression Resistance Priority


  • Content Compression Resistance Priority는 콘텐츠 크기보다 작아지지 않으려는 경향을 나타내는 우선순위이다.
  • 이것은 공간이 부족할 때, 어떤 뷰가 축소될지를 결정할 때 사용된다.
  • 우선순위가 높은 뷰는 가능한 한 축소되지 않으려 하며, 우선순위가 낮은 뷰는 공간 부족 시 먼저 축소된다.

즉, UIStackView가 너무 좁아질 때 뷰가 줄어드는 순서를 정하는 기준이 바로 Content Compression Resistance Priority이다.



3. 상황 예시


수평(.horizontal)으로 배열된 UIStackView 안에 두 개의 UILabel(왼쪽 레이블과 오른쪽 레이블)이 존재한다고 가정하자.

  • 왼쪽 레이블(leftLabel)의 텍스트는 "Author", "Released", "Pages" 등 고정적이며, 콘텐츠 크기가 변경될 가능성은 낮다.
  • 오른쪽 레이블(rightLabel)은 이름, 날짜, 페이지 수 등 콘텐츠의 길이가 달라지고 길어질 수 있다.

이때 원하는 레이아웃 조건은 다음과 같다:

  • 왼쪽 레이블은 추가 공간이 있어도 늘어나지 않고 자신의 크기만 유지한다.
  • 왼쪽 레이블은 공간이 부족해도 텍스트가 잘리지 않는다.
  • 오른쪽 레이블은 공간이 넉넉하면 늘어나지만, 공간 부족 시에는 축소될 수 있다.



4. 코드 예시


// 두 개의 레이블 생성
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 PriorityContent Compression Resistance Priority최종 동작
왼쪽 레이블 (leftLabel).required (높음).required (높음)크기 고정 (절대 늘어나거나 축소되지 않음)
오른쪽 레이블 (rightLabel).defaultLow (낮음).defaultLow (낮음)공간이 많으면 늘어나고, 공간이 부족하면 축소됨

즉, 왼쪽 레이블은 언제나 고정된 너비를 유지하고, 오른쪽 레이블이 남은 공간에 따라 확장 또는 축소되는 결과를 얻을 수 있다.



5. 요약


Priority의미 (역할)설정 방법
Content Hugging Priority추가 공간이 생겼을 때 콘텐츠 크기 이상으로 늘어나는 것을 방지높은 값을 설정하면 늘어나지 않음
Content Compression Resistance Priority공간이 부족할 때 콘텐츠 크기 이하로 줄어드는 것을 방지높은 값을 설정하면 축소되지 않음

두 Priority를 모두 높게 설정하는 경우, 레이블은 절대로 자신의 크기보다 늘어나거나 축소되지 않는다.
다음 두 줄이 핵심 코드이다:

leftLabel.setContentHuggingPriority(.required, for: .horizontal)
leftLabel.setContentCompressionResistancePriority(.required, for: .horizontal)

이 두 줄만으로 왼쪽 레이블이 자신의 크기를 엄격히 유지하면서, 오른쪽 레이블이 남은 공간을 유연하게 활용할 수 있는 원하는 레이아웃을 구현할 수 있다.

profile
iOS 개발자

0개의 댓글