본문 바로가기

iOS/AutoLayout

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

 

 

안녕하세요 :)  소들입니다!!!

저번 포스팅에서 Auto Layout이 무엇인지, Frame-Based Layout과 어떤 차이점이 있는지,

또 Top/Bottom Layout Guide와 Safe Area에 대해서 공부 했어요 :D

 

이번 포스팅에선 Intrinsic Content SIze

Auto Layout을 설정할 때 지정할 수 있는 Priority에 대해 알아보려고 해요 :))

모든 포스팅은 편의 말투로 합니다~!!

 

 

 

 

1. UIView와 UILabel의 Auto Layout 차이점 찾아보기

 

열어분,, AutoLayout이 뭐다???

Constraints를 이용해서 뷰의 "위치"와 "크기"를 "동적"으로 지정하는 것이라고 했음

물론 Width, Height는 정적으로도 지정 되지만 :)

 

따라서 만약 다음과 같이 노란 UIView를 만들 때 Auto Layout을 이용해서,

 

 

 

 

Safe Area와의 간격을 직접 Top은 50, Leading은 30, Trailing은 30만큼, Height는 200으로 고정

이렇게 지정할 수 있었음

 

 Auto Layout도 View의 위치와 크기를 지정하는 것이기 때문에,

결과적으로 Auto Layout을 통해 View "위치"와 "크기"를 알 수 있어야함

근데 위에서 Height는 200인 값으로 고정시켰지만, Width는 내가 값을 주지 않았음!!

 

하지만, 레이아웃단 에러는 나지 않음 :)

왜냐?? Constraints를 통해 Witdh를 계산해낼 수 있거든!!!!

Leading / Trailing Cosntraints에 의해 해상도 별로 width가 자동으로 지정됨

 

 

 

 

이런 식으로 :)

아하, Leading과 Trailing을 통해 Width가 동적으로 계산 되는구나를 알 수 있음!

자, 그럼 만약 여기서 내가 Trailing을 삭제하게 된다면 어떻게 될까!?

 

 

 

 

당연히 Width를 동적으로 계산할 수 없어서

Width Constraints를 추가하라며 레이아웃단 에러가 남

 

이 에러가 나는 이유는 UIView의 Width는 Intrinsic Content Size를 가지지 않기 때문인데,

이는 나중에 더 자세하게 설명할테니까 넘어가고 :)

 

이제 위와 똑같은 Constraints를 UIView가 아닌 UILabel로 대체해서 해보겠움

똑같이 Safe Area를 기준으로 Leading으로 30, Top, 50, Height 200을 줘 보면,

 

 

 

 

분명 Width가 없는 건 UIVIew일 때와 동일하지만,

레이아웃단 빨간 에러는 발생하지 않음 :)

 

 

 

 

물론 위처럼 Trailing이 없다며 경고 메세지는 나지만,

결론적으로 빨간 에러가 안 난다는 것에서 UIView와 뭔가 다른 게 느껴짐!?!?

이것이 바로, UILabel이 Intrinsic Content SIze를 가지기 때문임 :)

 

일단은 대충 

UILabel은 Intrinsic Content Size 때문에 Width를 지정하지 않아도 되는군...

ㅎㅏ고 넘어가셈

그럼 이제 드디어 대망의 Intrinsic Content SIze를 공부하러 가보잣

 

 

 

 

2. Intrinsic Content Size 

 

컨텐츠의 본질적인 크기

 

Intrinsic Content Size란 말 그대로 컨텐츠의 "본질적인 크기"를 가르킴 :)

위에서 Label의 Width를 우리가 지정하지 않았지만, 레이아웃단 에러가 나지 않은 이유는

Label은 Width 뿐만 아니라 Height에 대해 Intrinsic Content Size를 가지기 때문

 

아 그래서 Intrinsic Content Size가 먼데연

 

.

.

자, 우리가 다음과 같이 만약 Label의 Width와 Height를 각각 100과 50으로 줘버렸음

 

 

 

 

그럼 Label의 글자 크기가 위와 같을 땐 문제가 없음

근데 만약 내가 해당 글자의 크기를 키우고 폰트도 바꿔봤음

 

 

 

 

그러면 Constraints에 의해 Width가 100, Height가 50으로 지정됐기 때문에,

그 크기를 넘길 시 글자들은 짤려버림 (만약 글자 크기가 더 커지면 아예 글자가 모두 생략됨)

 

그러면 이러한 문제를 어케 해결하냐!? :)

그냥 쿨하게 Width와 Height Constraints를 지워버리는 것임!

왜냐? Label은 자체적으로 본질적인 Width와 Height, 즉 Intrinsic Content Size를 가지거든!

 

 

 

 

이렇게!! :)

Label 안에 들어가는 텍스트의 길이, 폰트에 따라

본질적인 Width, Height를 자체적으로 갖기 때문에, 

Label에 대해 Width, Height를 지정해주지 않아도 에러가 나지 않는 것임 :)

 

이렇게 Intrinsic Content Size를 가지는 대표적인 것들은 다음과 같음

 

 

  Intrinsic Contet Size Width Intrinsic Contet Size Height
UIView X X
UISlider O X
UILabel, UIButton, UISwitch, UITextField O O
TextView, ImageView Content에 따라 변화함

 

 

UIView에선 Width Constraint를 지정하지 않으면

Intrinsic Content Size Width를 가지지 않아서 레이아웃단 에러가 나지만,

UILabel에선 Width Constraint를 지정하지 않아도,

Intrinsic Content Size Width 즉, 본질적인 Width를 가지기 때문에 레이아웃단 에러가 나지 않음!

 

실제로, UIView와 Label의 IntrinsicContentSize 프로퍼티를 출력해보면,

 

 

print(myView.intrinsicContentSize)          // (-1.0, -1.0)
print(myLabel.intrinsicContentSize)         // (160.0, 20.3)

 

 

UIVIew는 (-1.0, -1.0)으로 아마 가지지 않는다는 기본값을 갖고 있는 것 같고,

UILabel은 해당 Label의 본질적인 크기를 가지고 있음

(참고로, IntrinsicContentSize 프로퍼티는 UIView의 멤버임)

 

이제 이해가 갔길 :)

뭐 실제로 CustomView에 Intrinsic Content Size를 적용하는 방법은

나중에 하고싶을 때 포스팅 하겠움

 

 

 

3. Priority

 

자, 아까 Label은 Intrinsic Content Size를 Width, Height 모두 가지고 있기 때문에,

Width를 지정해주지 않아도 레이아웃단 에러는 나지 않았지만,

 

 

 

 

이렇게...... 경고.. 정도는 뜬다고 했음

자, 이게 무슨 경고냐... Label 2개로 예를 보여주겠음

 

 

 

 

이렇게 Intrinsic Content Size를 가지는 Label이 각각 위처럼 Constraints를 갖고 있음

(Width, Height는 지정 X)

 

 

 

 

이럴 경우,

왼쪽 Label은 Trailing이 없다고 / 오른쪽 Label은 Leading이 없다는 경고가 뜸

 

 그러면 왼쪽 Label의 Trailing을 오른쪽 Label의 Leading으로 Contraints를 맞춰주면 되지 않나요?!

뭐 1차원적으론 맞음!! 그래서 그렇게 Constraints를 추가해주면,

 

 

 

 

이번엔 빨간 오류가 떠버림 삐용삐용

왼쪽 라벨의 horizontal hugging을 251에서 252로 증가시켜서, 다른 view들 보다 먼저

intrinsic width를 유지하래.. 그러면서 Change Priority를 하래.....

 

따라서... Priority를 알아보기 위한... 글임...

 

 

 

3-1. Content Hugging Priority

 

자, 위에서 빨간 에러가 떴던 이유는 

 

 

 

 

이렇게 Label끼리 서로 Leading / Trailing을 설정해 버린 경우,

둘 중 하나는 Intrinsic Width를 유지하지 못하게 됨

 

왜냐??

Leading / Trailing Contraints에 의해서

둘 중 하나의 Width는 "동적"으로 설정 돼야 하거든 :)

 

 

 

 

이렇게 왼쪽 Label이 Intrinsic Width를 지키지 못하고 크기가 늘어나거나,

 

 

 

 

이렇게 오른쪽 Label이 Intrinsic Width를 지키지 못하고 크기가 늘어나야 한다는 것임

근데 지금은 둘 다 우선순위가 같아서, 어떤 놈이 늘어나야 할지 모르는 것임

따라서, 이때 

 

두 오브젝트 중에 한 놈이 "커져야" 하는 상황일 때

어떤 놈이 Intrinsic Size를 유지 못하고 늘어날래???

=> 우선순위 높은 놈은 Intrinsic Size를 유지, 낮은 놈이 늘어남

 

을 설정해 주는 것이 바로 Hugging Priority

따라서 위와 같은 상황일 때,

 

 

 

 

왼쪽 Label의 Hugging Priority Horizontal을 기본 값인 251보다 높여주면,

왼쪽 Label은 자신의 Intrinsic Width를 유지하고,

오른쪽 Label은 Intrinsic Width를 유지하지 못하고 Width가 늘어남

 

반대로,

오른쪽 Label의 Hugging Priority Horizontal을 왼쪽 Label의 값인 252보다 높여주면,

 

 

 

 

오른쪽 Label은 자신의 Intrinsic Width를 유지하고,

왼쪽 Label은 Intrinsic Width를 유지하지 못하고 Width가 늘어남 :)

 

만약 Height가 위와 같은 상황에선 Vertical의 Priority를 조정하면 되는 것:)

이해가 되셨길!!

 

 

 

3-2. Content Compression Resistance Priority

 

이것은 Hugging과는 반대의 상황임

우리가 왼쪽 Label의 Hugging Priority를 높여서 다음과 같이 되었을 때,

 

 

 

 

만약 왼쪽 Label에 주저리 주저리 엄~~청 길게 썼음

 

 

 

 

그러면 이렇게 또 레이아웃단 에러가 남

 

왼쪽 라벨의 horizontal compression resistance를 750에서 751로 증가시켜서,

다른 view들 보다 먼저 intrinsic width를 유지하란 것

 

왼쪽 Label이 너무 길어져서 오른쪽 Label의 영역을 넘어 설 때,

둘 다 우선 순위가 같아서, 어떤 놈이 줄어들어야 할지 모르는 것임

따라서 이때,

 

두 오브젝트 중에 한 놈이 "작아져야" 하는 상황일 때

어떤 놈이 Intrinsic Size를 유지 못하고 줄어들래???

=> 우선순위 높은 놈은 Intrinsic Size를 유지, 낮은 놈이 줄어듬

 

을 설정해 주는 것이 바로 Compression Resistance Priority

 

언뜻 보면 Hugging Priority와 비슷해 보이지만,

Hugging Priority는 "커져야" 할 때를 설정하는 것이고,

Compression Resistance Priorty는 "작아져야" 할 때를 설정하는 것임!

 

따라서 위와 같은 상황일 때,

 

 

 

 

왼쪽 Label의 Compression Resistance Priority를 기본 값인 750보다 높여주면,

왼쪽 Label은 늘어날 수 있을 때까지 자신의 Intrinsic Width를 유지하고,

오른쪽 파란 Label은 Intrinsic Width를 유지하지 못하고 압축되어 버림

(아예 사라져버렸네 껄껄)

 

반대로,

 오른쪽 Label의 Compression Resistance Priority를 왼쪽 Label의 값인 751보다 높여주면,

 

 

 

 

오른쪽 Label은 자신의 Intrinsic Width를 유지하고, 왼쪽 Label이 압축되어 버림 :)

 

 

 

 

 

+ Priority 사용 예제

 

만약 다음과 같이 게시글을 표시할 때,

제목과 작성자를 설정해야 한다면

 

 

 

 

이때 작성자 Label보다 글 제목 Label의 Width가 길어져야 하기 때문에

글 제목 Label 보다 작성자 Label의 Hugging Priorty가 더 높아야 함!!

 

만약, 글 제목을 다음과 같이 받아와서 표시하는데 제목이 긴 경우에는, 

 

 

 

 

이땐 글 제목이 아무리 길어도

작성자 Label은 압축 시키면 안 되고 Intrinsic Width를 유지해야 하기 때문에

글 제목 Label보다 작성자 Label의 Compression Resistance Priorty가 더 높아야 함 :)

 

 

 

 

 

.

.

 

이 외에 Constraints가 갖는 Priority에 대해서는

나중에 좀 더 자세히 포스팅 하겠습니다 :)

 

틀린 내용이 있을 수 있으니 발견하거나,

궁금한 점이 있다면 언제든 댓글 주세요!! 

 

 



Calendar
«   2024/04   »
1 2 3 4 5 6
7 8 9 10 11 12 13
14 15 16 17 18 19 20
21 22 23 24 25 26 27
28 29 30
최근 댓글
Visits
Today
Yesterday