애플사이다의 iOS 개발 일지

[AutoLayout] CHCR이란? Label의 default CHCR 값은? - 공식문서 오류 정정 본문

iOS/영문 공식문서 뜯어보기-iOS

[AutoLayout] CHCR이란? Label의 default CHCR 값은? - 공식문서 오류 정정

Applecider 2022. 6. 16. 13:12

CHCR은 Compression-Resistance 및 Content-Hugging를 뜻한다.

 

화면에 여러 가지 View를 나타내는 경우, 이 CHCR 값을 조정하게 되는데

(특히 StackView 내부에 여러 가지 View를 ArrangedSubviews로 올리는 경우)

관련 개념을 알아보다가 공식문서에서 몇몇 오류를 발견해서 정리해봤다.


🍎 Intrinsic Size란?

원래는 View의 위치 및 크기 (Origin 및 Size)를 모두 지정해줘야 하는데,

📐 일부 View는 View 내부의 컨텐츠에 따라 자체적으로 Size를 가지도록 되어있다.

이걸 Intrinsic Size (내재적인 크기, 자체적인 크기)라고 부른다.

 

예를 들어 Button의 Intrinsic Size는 뭘까? 
“Button 내부의 텍스트 + default margin” 크기가 Button의 Intrinsic Size이다. (font 등의 영향을 받는다.)

 

Apple Archive의 Anatomy of a Constraint에 Intrinsic Size 목록이 나와있다.

View 종류별 Intrinsic Size

  • UIView : 없음
  • Slider : 높이만 가능 (iOS) ← width는 오타인듯 (공식문서 오류)
  • Label, Button, Switch, Text Field : 높이/너비 가능 (위치만 정해주면, 크기는 자동으로 반영된다는 뜻)
  • TextView / ImageView : 상황에 따라 다름. 스크롤이 없으면 가능

🔎 Intrinsic Size를 왜 도입했을까?

View를 화면에 나타낼 때, 모든 View에 대해 Origin 및 Size를 일일이 설정할 필요가 없어지므로

관리할 constraint 개수가 줄어들어서 편리하다.

🍎 CHCR이란?

CHCR은 Compression-Resistance 및 Content-Hugging를 의미한다.

Intrinsic Content Size를 활용하여 Layout을 설정하려면 CHCR 조정이 필요하다.

 

예를 들어 화면에 여러 가지 View를 올리는 경우, Device Screen 크기에 따라 유동적으로 나타내기 위해

특정 ImageView는 Screen 너비만큼 늘어나게 하고, 특정 Label은 텍스트가 짤리지 않도록 설정해야 할 때가 있다.

 

이때 CHCR은 어떻게 사용할까?

이렇게 ImageView가 늘어나도록 하는 것은 Content-Hugging 우선도를 감소시키고,
Label이 잘리지 않도록 하는 것은 Compression-Resistance 우선도를 증가시켜서 구현하면 된다.

 

CHCR을 정확히 정의해보자.

CHCR 설명

  • Compression-Resistance (압축 저항) : 외부 압력에 의해 콘텐츠가 잘리지 않도록 버티는 힘
  • Content-Hugging (컨텐츠 허깅) : Intrinsic Content Size와 딱맞게 줄어들려고 하는 힘

둘은 반대 개념이 아니며, 다른 constraint와 마찬가지로 CHCR에도 우선도가 적용된다.

우선도 (Constraint Priority)

constraint를 동일한 영역에 대해 중복으로 설정할 수 있는데, 이때 우선순위가 높은 constraint에 따라 배치한다.
(화면에 나타낼 때 우선순위가 낮은 constraint는 무시된다.)

우선도는 1~1000 사이에서 조절할 수 있다.

🍎 CHCR 값을 설정하는 방법

View의 CHCR 값을 설정하는 방법은 두 가지가 있다.

 

1. UILayoutPriority의 타입 프로퍼티 활용

간단하게 사용할 수 있도록 .defaultLow, .defaultHigh, .required 가 있다.

rawValue는 각각 1000, 750, 250 이다.

// 타입 프로퍼티 활용
label.setContentHuggingPriority(.required, for: .horizontal)
label.setContentHuggingPriority(.defaultHigh, for: .horizontal)  
label.setContentHuggingPriority(.defaultLow, for: .horizontal)  

// 프로퍼티별 rawValue
.required    == 1000
.defaultHigh ==  750
.defaultLow  ==  250

검색 키워드 : ios chcr required rawvalue

when-to-use-uilayoutpriority-required-in-setcontentcompressionresistanceprior

 

2. UILayoutPriority의 init(rawValue: Float) 활용

우선도는 1~1000의 범위 내에서 원하는 값을 지정할 수 있다.

// rawValue 활용
label.setContentHuggingPriority(.init(rawValue: 150), for: .horizontal)

🍎 공식문서 오류 - default CHCR 값

공식문서 내용 중에서 잘못된 정보는 아래와 같다.

오류 - Name Label의 Hugging은 251로 표기되어 있음 (실제로는 250)

위 표처럼 Label의 default Hugging은 251이라고 표기되어 있지만,

실제로는 250이다.

이것 때문에 StackView에 여러 개의 Label을 넣고, CHCR 값을 조정하는 과정에서 삽질을 많이 했다...

 

Debug View Hierarchy 탭에서 Label의 Hugging 값을 직접 확인해봤다.

Label의 default CHCR

  • 왼쪽에 표시한 아이콘을 탭하면 Debug View Hierarchy를 볼 수 있다.
  • 화면에서 원하는 Label을 클릭하면, 우측에서 관련 정보를 확인할 수 있다.
  • 현재 선택된 Label (5% 텍스트가 들어있는 Label)의 CHCR 값을 따로 지정하지 않았으므로 default 값으로 설정되어 있다.
    Label의 default Hugging은 Horizontal, vertical 모두 250이다.

예제코드 - CHCR priority 설정하기

참고로 5% 텍스트가 들어있는 Label은 아래 코드로 생성했다.

priority를 .defaultHigh로 변경하면 Hugging 값이 250에서 750으로 바뀐다.

private let bargainRateLabel: UILabel = {
    let label = UILabel()
    label.translatesAutoresizingMaskIntoConstraints = false
    label.textAlignment = .right
    label.font = Design.bargainRateLabelFont
    label.textColor = Design.bargainRateLabelTextColor
    // ✅ Hugging 값이 250 (default) -> 750 (.defaultHigh)으로 변경됨
    label.setContentHuggingPriority(.defaultHigh, for: .horizontal)  
    return label
}()
  • setContentHuggingPriority, setContentCompressionResistancePriority 메서드를 통해 CHCR priority를 설정한다.

 

- Reference

 

🍎 포스트가 도움이 되었다면, 공감🤍 / 구독🍹 / 공유🔗 / 댓글✏️ 로 응원해주세요. 감사합니다.

Comments