iOS/UIKit

[AutoLayout] Hugging과 Resistance (feat. intrinsic content size)

TDCIAN 2023. 4. 24. 22:18

미안하다,,, 달리 대표할 만한 이미지가 안 떠올라서 어그로 끌었다,,,

 

 

 

Q. iOS Application 개발 과정에서 intrinsic content size, content hugging, compression resistance의 정의와 관계, 사용 방법에 대해서 Swift 코드와 함께 설명해 줘

 

A. iOS 애플리케이션 개발에서 뷰의 크기와 레이아웃을 다루는 것은 중요한 부분입니다.

 

1. intrinsic content size

intrinsic content size는 뷰의 내용물(content)의 크기에 대한 정보를 뜻합니다. 예를 들어, UILabel의 intrinsic content size는 텍스트의 길이와 폰트 크기에 따라 결정됩니다. 이때 뷰의 크기는 내용물(content)의 크기와 동일하게 설정됩니다.

 

let label = UILabel()
label.text = "Hello, World!"
label.font = UIFont.systemFont(ofSize: 17)
label.sizeToFit() // 뷰의 크기가 intrinsic content size에 맞게 설정됩니다.

 

이렇게 해 놓으면 자연스럽게 눈이 멀게 되실 것 같으니 한글도 넣어봅시다.

- UIView는 intrinsic content size 없답니다.

- UISlider는 width에 대한 intrinsic content size만 존재한답니다.

- UILabel, UIButton, UISwitch, UITextField는 intrinsic content size가 width와 height 모두 있답니다.

- UITextView와 UIImageView의 intrinsic content size는 컨텐츠에 따라 변화할 수 있답니다.

 

 

2. Content Hugging

Content Hugging은 뷰가 자신의 내용물(content)을 얼마나 강하게 끌어안고(hug) 있는지에 대한 정보를 뜻합니다. 예를 들어, UILabel의 content hugging priority는 높을수록 텍스트에 따라 뷰의 크기가 커지는 것을 방지합니다.

let label = UILabel()
label.text = "Hello, World!"
label.font = UIFont.systemFont(ofSize: 17)
label.setContentHuggingPriority(.defaultHigh, for: .horizontal) // 뷰가 가로 방향으로 내용물(content)을 강하게 끌어안음

 

3. Compression Resistance

Compression resistance는 뷰가 자신의 내용물(content)을 얼마나 강하게 보호하는지에 대한 정보를 뜻합니다. 예를 들어, UILabel의 compression resistance priority가 높을수록 텍스트에 따라 뷰의 크기가 작아지는 것을 방지합니다.

let label = UILabel()
label.text = "Hello, World!"
label.font = UIFont.systemFont(ofSize: 17)
label.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal) // 뷰가 가로 방향으로 내용물(content)을 강하게 보호함

 

 

 

Q. iOS Application 개발 과정에서 intrinsic content size, content hugging, compression resistance의 관계에 대해 좀 더 자세히 설명해 줘

 

A. intrinsic content size, content hugging, compression resistance는 서로 밀접하게 연관된 개념으로, 뷰의 크기와 레이아웃을 제어하는 데에 중요한 역할을 합니다.

 

먼저, intrinsic content size는 뷰의 내용물(content)에 따라 결정되는 뷰의 크기를 의미합니다. 뷰의 내용물이 변경되면, intrinsic content size도 함께 변경되어 뷰의 크기를 업데이트 합니다. 예를 들어, UILabel의 intrinsic content size는 텍스트의 길이와 폰트 크기에 따라 결정됩니다.

 

그리고 content hugging과 compression resistance는 뷰의 크기가 intrinsic content size보다 작거나 큰 경우 뷰의 크기를 조정하는 데에 사용됩니다.

 

content hugging은 뷰가 자신의 내용물(content)을 얼마나 강하게 끌어안고(hug) 있는지에 대한 정보를 뜻합니다. 이때 뷰의 크기는 intrinsic content size보다 작은 경우, content hugging priority에 따라 뷰가 내용물을 충분히 보호하기 위해 intrinsic content size보다 크게 유지됩니다.

 

반면, compression resistance는 뷰가 자신의 내용물을 얼마나 강하게 보호하는지에 대한 정보를 뜻합니다. 이때 뷰의 크기는 intrinsic content size보다 큰 경우, compression resistance priority에 따라 뷰가 내용물을 충분히 보호하기 위해 intrinsic content size보다 작게 유지됩니다.

 

즉, intrinsic content size, content hugging, compression resistance는 서로 밀접한 관계를 갖고 있으며, 뷰의 크기와 레이아웃을 제어하는 데에 중요한 역할을 합니다. 이들 개념을 적절하게 사용하여 뷰의 크기와 레이아웃을 제어하면, iOS 애플리케이션 개발에서 뷰의 디자인을 보다 쉽고 정확하게 다룰 수 있습니다.

 

 

 

 

 

 

 

자 이제 직접 함 봅시다!

 

Content Hugging Priority

사스케와 나루토 일단 모두 vertical 위치는 center로 변경하였습니다. 그 후 사스케(왼쪽)은 leading으로 20을, 나루토(오른쪽)은 trailing으로 20을 주었습니다. 지금까지는 별 문제가 없습니다.

 

 

하지만 사스케와 나루토 사이에 20이라는 간격을 부여하니 붉게 상기되어 버렸습니다.

이미 화면 좌측에 'Set horizontal hugging priority to 252'라는 힌트가 보이네요?

나루토와 사스케 모두 Content Hugging Priority의 값이 251로 비등비등 합니다.

 

여기서 사스케의 Content Hugging Priority의 값을 252로 올려보겠습니다.

(사진 우측 하단에 Content Hugging Priority 항목이 보이시죠?) 

 

사스케(왼쪽)의 Horizontal Hugging Priority를 나루토(오른쪽)보다 높게 한 경우 (252 : 251)

이번에는 나루토의 Horizontal Content Hugging Priority 값을 253으로 올려보겠습니다.

 

 

언뜻 보기에

'이상하다 Priority 값이 높으면 높은쪽이 더 크게 보여야 되는 거 아닌가...?'

라는 생각이 드실 수 있습니다.

 

일단 전 처음 봤을 때 들었어요ㅎㅎㅋㅋ...

 

그런데 아까 처음에 Hugging Priority는 '강하게 끌어안고(hug) 있는지에 대한 정보'라고 말씀 드렸었지요?

줄다리기를 생각해보시면 더 쉽겠네요.

 

줄다리기는 더 강한 쪽으로 끌려가게 되어 있으니까요

 

 

 

 

Compression Resistance Priority

이번엔 Compression Resistance Priority의 예시를 한 번 봅시다.

 

사스케(왼쪽)와 나루토(오른쪽) 사이에 아직 horizontal spacing이 설정되어 있지 않아 평화롭습니다.

둘 사이에 20이라는 간격을 줘보겠습니다.

20이라는 간격을 주니 다음과 같이 붉게 달아오른 게 보입니다.

이 상황에서 사스케를 사스케 * 10으로 바꿔 intrinsic content size의 넓이를 더 키워보겠습니다.

 

hint를 보면 사스케 쪽에는 'Set horizontal compression resistance priority to 749', 나루토 쪽에는 'Set horizontal compression resistance priority to 751'이라는 내용이 뜨네요.

기본 값은 Horizontal과 Vertical 모두 750입니다

사스케와 나루토 모두 750이라는 값을 갖고 있는데, 나루토의 Compression Resistance Priority값을 751로 올려보겠습니다.

 

둘 사이의 간격은 20으로 유지 된 상태에서, 사스케가 자기 자신이 갖고 있는 콘텐츠보다 찌그러져 있는 게 확인됩니다.

이번에는 사스케의 Compression Priority를 나루토보다 높은 752로 변경해 보겠습니다.

 

사스케가 나루토를 완전히 삼켜버렸습니다...

 

 

Content Hugging Priority 때는 숫자가 더 높은 쪽으로 숫자가 더 낮은 쪽이 끌려가는 모습이었는데,

Compression Resistance Priority에서는 숫자가 더 높은 쪽이 숫자가 더 낮은 쪽보다 자신의 고유한 모습을 더 유지하는 모습입니다.

(나루토가 Compression Resistance Priority가 더 높았을 때는 사스케의 intrinsic content size가 자신의 영역을 침범할 때도 자신의 고유한 모습을 유지했었죠)

 

앞서 설명한 바와 같이 compression resistance는 뷰가 '자신의 내용물을 얼마나 강하게 보호하는지에 대한 정보'이기 때문입니다.

 

잘 견딘다 이말입니다

 

 

결론!

Content Hugging Priority는 줄다리기 같이 Priority가 더 높은 쪽이 상대방을 끌어당김

Compression Resistance Priority는 금강불괴 같이 Priority가 더 높은 쪽이 자신의 본 형태를 유지함

 

 

 

 

 

 

참고 내용

https://developer.apple.com/library/archive/documentation/UserExperience/Conceptual/AutolayoutPG/AnatomyofaConstraint.html

 

Auto Layout Guide: Anatomy of a Constraint

 

developer.apple.com

https://babbab2.tistory.com/135

 

iOS) Auto Layout 정복하기 (3/5) - IntrinsicContentSize, Hugging Priority/ Compression Resistance Priority

안녕하세요 :) 소들입니다!!! 저번 포스팅에서 Auto Layout이 무엇인지, Frame-Based Layout과 어떤 차이점이 있는지, 또 Top/Bottom Layout Guide와 Safe Area에 대해서 공부 했어요 :D 이번 포스팅에선 Intrinsic Conten

babbab2.tistory.com