티스토리 뷰

반응형

안녕하세요 :) Zedd입니다.

오늘은...! translatesAutoresizingMaskIntoConstraints..!을 정확히 알아보는 공부~.~



translatesAutoresizingMaskIntoConstraints



사실 엄청 많이 보셨을 코드에요. 


self.view.translatesAutoresizingMaskIntoConstraints = false


뭐 이런거..보통 어떤 특정한 View를 가지고 저 프로퍼티를 호출하죠.

그리고 이것들은 언제보냐? 

보통 Constraint를 코드로 조정해야 할 일이 있을 때 호출합니다.

보통...? 아니 저같은...사람은....스토리보드를....많이 써서..스토리보드안에서 막 Constraint주고 막 그러는데..! 막 어쩔 때 보면 어쩔 수 없이 코드로 Constraint를 줘야 할 때가 있죠..!!!!! 

그때 위 translatesAutoresizingMaskIntoConstraints를 호출합니다. 


Q : 왜?


ㅇㅋㅇㅋ

일단 모르면 Apple문서 ㄱ 

일단 먼저, translatesAutoresizingMaskIntoConstraints는 UIView의 인스턴스 프로퍼티에요.


A Boolean value that determines whether the view’s autoresizing mask is translated into Auto Layout constraints.


View의 autoresizing  mask가  Auto Layout constraints으로 변환(translated)되는지 여부를 결정하는 Bool값입니다.


;;;;;아니 머래는거얌..일단 autoresizing  mask가 뭐지..? Constraint는 알겠는데 말이죠..

그럼 translatesAutoresizingMaskIntoConstraints의 Discussion을 보기 전에..!

autoresizing  mask가 뭔지 알아봅시다.


autoresizing  mask



autoresizing  mask도 translatesAutoresizingMaskIntoConstraints과 마찬가지로, UIView의 인스턴스 프로퍼티입니다.

정의는 

An integer bit mask that determines how the receiver resizes itself when its superview’s bounds change.


SuperView의 bounds가 변경 될 때, receiver의 size를 조정하는 방법을 결정하는 정수 비트 마스크입니다.

아 비트마스크..


autoresizing  mask는 "정수 비트 마스크"라니까 뭔가 타입이 정수? 뭐 그런건가 Int가 할 수 있지만...아닙니다. UIView에 있는 UIViewAutoresizing의 "구조체"의 인스턴스 입니다. 


UIViewAutoresizing구조체의 정의는


Options for automatic view resizing.

자동의 View resizing옵션..?



이 구조체 안에는 static변수들이 이렇게 있군요..

뭔가 이름 앞에 다 flexible이 붙은 걸 보니, 뭔가 늘고 주는게? 그런게 가능한 것들 같네요.

뒤에 붙은 이름들은 우리가 constraint에서 많이 보던..그런 애들이네요..!

아무튼 UIViewAutoresizing애는 이런 static한 애들이 있고, 

이 UIViewAutoresizing의 인스턴스가 autoresizing  mask라는 게 결론이죠.



기본값은 None인가 보네용


사실 이까지 말하면 

ㅋ......아...응...ㅎ........와.....흥미롭네......대박...하실텐데요.


사실 우리는 autoresizing  mask를 많이 봤습니다...!

다들 한번쯤은 보셨을 거에요.

바로



이거죠...! 

이렇게 UIView를 추가하고 아무런 constraint를 주지 않았어요. 그러면..



아이패드에서는 이러케댐...ㅠ

우리는 어느 디바이스에서나 왼쪽에서는 얼마 떨어져있고, 오른쪽에서는 얼마 떨어져있었으면 좋겠어!!!!해가지고


뭐 이런식으로 Constraint를 관계를 이용하여 주게 됩니다. 


이젠 아이패드에서도 동일한 간격으로 나오게 되네요.

하지만 이제 constraint를 없애주겠습니다. 전부요 ㅇㅇ



그리고 여길 건들여볼게요.

여러분 어렵게 생각하지 마세요. 진짜 자동으로 리사이징 해주겠다 ㅇㅇ 이겁니다. 

오른쪽에는 움직이면서 보여주니까 더 알기 쉬울거에요.



그리고 이렇게 그림으로 아주 쉽게 내가 원하는 조건을 줬어요. 음..나는 디바이스의 크기에 따라서 막 넓어지고 좁아지는게 자동으로 되면 좋겠어!!!!




이렇게 되면, Constraint가 1도 없음에도 불구하고 아주 잘 늘어나는 것을 볼 수 있죠.

이게 그냥 Auto Resizing이에요. 

뭐 배경화면 줄 때 좋겠죠? 




이렇게만 지정해주면..




constraint를 1도 안줘도 알아서 늘어나니깐~~~~~~

그럼 이어서 translatesAutoresizingMaskIntoConstraints의 Discussion으로 가봅시다.


translatesAutoresizingMaskIntoConstraints의 값이 true이면(Bool타입이었죠?), 

시스템은 View의 autoresizing  mask(방금 말한애)로 지정된 행동?(behavior)을 복제하는 Constraint집합을 만듭니다.

또한 View의  frame, bounds 또는 center프로퍼티를 사용하여 View의 크기와 위치를 수정하여 auto layout에서 정적인 프레임 기반 레이아웃을 만들 수 있습니다. autoresizing mask constraint는 View의 크기와 위치를 완전히(fully specify) 지정합니다.

따라서 충들을 일으키지 않고, 이 크기 또는 위치를 수정하기 위해 추가 constraint를 추가 할 수 없습니다.

auto layout을 사용하여 View의 크기와 위치를 동적으로 계산하려면, 이 프로퍼티를 false로 설정 한 다음, View에 모호(ambiguous)하지 않고 충돌하지 않는(nonconflicting) constraint집합을 제공해야 합니다.

기본적으로 프로그래밍 방식으로 만드는 모든 View에 대해 이 프로퍼티는 true로 설정됩니다.

Interface Builder(=스토리보드)에서 View를 추가하면, 시스템은 이 프로퍼티를 false로 자동 설정합니다.


두번째 줄에서 행동??behavior? 그게 먼데ㅡㅡ



우리가 자주 사용하는 sizeToFit()도 Resizing Behavior중에 하나네요 :)


여러분 translatesAutoresizingMaskIntoConstraints의 discussion을 진짜 하나하나 다시 읽어보면 조금 이해?가 될거에요.

그러니까 한줄한줄 읽어봅시다.


translatesAutoresizingMaskIntoConstraints의 값이 true이면,

시스템은 View의 autoresizing  mask(방금 말한애)로 지정된 행동?(behavior)을 복제하는 Constraint집합을 만듭니다.


그러니까,  translatesAutoresizingMaskIntoConstraints가 true라고 치고.




이렇게 autoresizing을 줘봅시다. 

그러면 시스템은, View의 autoresizing  mask로 지정된 behavior를 복제하는 Constraint집합을 만듭니다.

그러니까, 우리가 이렇게 autoresizing준거를 사용해서..!! constraint집합을 만든다는것이죠.


또한 View의  frame, bounds 또는 center프로퍼티를 사용하여 View의 크기와 위치를 수정하여 auto layout에서 정적인 프레임 기반 레이아웃을 만들 수 있습니다

autoresizing mask constraint는 View의 크기와 위치를 완전히(fully specify) 지정합니다.

따라서 충들을 일으키지 않고, 이 크기 또는 위치를 수정하기 위해 추가 constraint를 추가 할 수 없습니다.(핵심)


네 그렇습니다. 이렇게 autoresizing을 이용해서 View에게 behavior?를 주면, View의 크기와 위치는 "완전히" 고정된 상태이며, 우리가 "아 ㅎ 이때는 좀 leading constant를 주고싶네"하고 constraint를 추가하지 못한다는 것이죠.


auto layout을 사용하여 View의 크기와 위치를 동적으로 계산하려면, 이 프로퍼티를 false로 설정 한 다음, View에 모호(ambiguous)하지 않고 충돌하지 않는(nonconflicting) constraint집합을 제공해야 합니다.


조금 뭔가 감이 잡히시나요?

제가 예제를 하나 준비했습니다.



imageView를 하나 추가해주고, AutoResizing을 줬어요. constraint는 1도 없이 말이죠.

그리고 이제 constraint를 하나 추가해보겠습니다.


NSLayoutConstraint.activate([ self.imageView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,constant: 10)])


leading에 constant를 10으로 줬어요. 

그리고 실행해볼까요? 

그러면 이러한 오류를 보게 됩니다. 우리가..많이 봤던 오류죠. 음..오류라고 해야하나? 일단 앱이 죽지는 않지만...암튼 이렇게 뭐라뭐라 하는 경고가 뜹니다.

맨날 이거 보고 아 ㅎ뭐여ㅋ;ㅋㅎㅋ하고 지나쳤을 분들이 많이 계실텐데요. 이 경고에 모든 것이 들어있습니다.

볼까요? 


[LayoutConstraints] Unable to simultaneously satisfy constraints.

Probably at least one of the constraints in the following list is one you don't want.


[LayoutConstraints] 제약 조건을 동시에 만족시킬 수 없습니다.

아마도 다음 목록에있는 제약 중 적어도 하나는 원치 않는 것입니다.



Try this: 

(1) look at each constraint and try to figure out which you don't expect; 

(2) find the code that added the unwanted constraint or constraints and fix it. 



다음을 시도해보십시오.

(1) 각 제약을 살펴보고, 기대하지 않는 것을 찾아 내려고 시도하십시오.

(2) 원하지 않는 제약 조건 또는 제약 조건을 추가 한 코드를 찾아 수정하십시오.



(Note: If you're seeing NSAutoresizingMaskLayoutConstraints that you don't understand, refer to the documentation for the UIView property translatesAutoresizingMaskIntoConstraints) 


(참고 : 이해할 수없는 NSAutoresizingMaskLayoutConstraints가 보이면 UIView 속성 translationsAutoresizingMaskIntoConstraints에 대한 도큐먼트를 참조하십시오.)



"<NSAutoresizingMaskLayoutConstraint:0x60400028d0c0 h=-&- v=-&- UIImageView:0x7fbabad23e00.width == UIView:0x7fbabac76300.width   (active)>",

"<NSLayoutConstraint:0x60000028d890 H:|-(10)-[UIImageView:0x7fbabad23e00]   (active, names: '|':UIView:0x7fbabac76300 )>"

)


그리고 이 난해한 부분..
잘보면 아~~하실겁니다. 하나하나 보죠.

"<NSAutoresizingMaskLayoutConstraint:0x60400028d0c0 h=-&- v=-&- UIImageView:0x7fbabad23e00.width == UIView:0x7fbabac76300.width  (active)>"

야ㅇㅇ 니가 AutoResizingMask를 줬는데 
니 ImageView랑 UIView(즉 현재 imageView의 superView)의 width는 같애ㅇㅇ;
왜냐???


우리가 이렇게 지정해줬기 때문이죠. View의 widht와 height는 View의 크기와 상관없이 늘어들고 줄어드는게 자동으로 되죠.


다음 로그.


"<NSLayoutConstraint:0x60000028d890 H:|-(10)-[UIImageView:0x7fbabad23e00]   (active, names: '|':UIView:0x7fbabac76300 )>"

)


야;;ㅎ근데 니가 constraint를 하나 줬는데 니 imageView가 UIView(imageView의 superView)에서  (H는  horizontal direction을 의미) UIImageView왼쪽에 ㅣ-(10)-이 있으니까 UIView의 leading에서 10만큼 떨어져있게 해놨네 ㅎㅎ가 되는겁니다.


그럼 시스템입장에서는 아주 난감한 상황이죠.

1번에서는 


A : 야ㅋㅎㅋㅎ SuperView의 widht랑 imageView의 width는 같애!!!!!!

B :  ㄴㄴ아님. imageView는 superView의 leading에서 10만큼 떨어뜨려줘 ===> 이 말은 즉, superView의 width와 imageView의 width가 다르다는 말.


iOS : @_@


그래서 iOS는 선택을 합니다. 


Will attempt to recover by breaking constraint 

<NSLayoutConstraint:0x60000028d890 H:|-(10)-[UIImageView:0x7fbabad23e00]   (active, names: '|':UIView:0x7fbabac76300 )>


야 ㅎ <NSLayoutConstraint:0x60000028d890 H:|-(10)-[UIImageView:0x7fbabad23e00](active, names: '|':UIView:0x7fbabac76300 )> 이 제약조건(우리가 코드로 준 제약조건)을 내가 뿌시고(breaking) 복구를 시도했어.


그럼 이 제약조건이 무시가 된거나 다름없으니, 결과는 superView의 width와 imageView의 width가 동일해야겠네요.


ㅇㅇ그러하다


Make a symbolic breakpoint at UIViewAlertForUnsatisfiableConstraints to catch this in the debugger.

The methods in the UIConstraintBasedLayoutDebugging category on UIView listed in <UIKit/UIView.h> may also be helpful.



디버거에서 이것을 잡으려면 UIViewAlertForUnsatisfiableConstraints에서 심볼릭 브레이크 포인트를 만듭니다. <UIKit / UIView.h>에 나열된 UIView의 UIConstraintBasedLayoutDebugging 카테고리의 메서드도 유용 할 수 있습니다.


A : 야ㅋㅎㅋㅎ SuperView의 widht랑 imageView의 width는 같애!!!!!!

B :  ㄴㄴ아님. imageView는 superView의 leading에서 10만큼 떨어뜨려줘 ===> 이 말은 즉, superView의 width와 imageView의 width가 다르다는 말.


A 승.
왜 승이죠? 위 Discussion에서 말했죠.

autoresizing mask constraint는 View의 크기와 위치를 완전히(fully specify) 지정합니다.


따라서 충들을 일으키지 않고, 이 크기 또는 위치를 수정하기 위해 추가 constraint를 추가 할 수 없습니다.



근데 B가 화나죠. 아니 나는 진짜 무조건 superView의 leading에서 10만큼 떨어져있어야 한단 말이야........진짜....
그럴때 바로


self.imageView.translatesAutoresizingMaskIntoConstraints = false


translatesAutoresizingMaskIntoConstraints를 false로 만들어주는 것입니다.

그리고 실행하면...! imageView가 보이지 않는 상황이 만들어지는데..UIView는 intrinsicContentSize를 가지고 있지 않기 때문에, 제약조건을 완벽하게 주지 않으면 화면에서 보이지 않습니다.


self.imageView.translatesAutoresizingMaskIntoConstraints = false


NSLayoutConstraint.activate([self.imageView.leadingAnchor.constraint(equalTo: self.view.leadingAnchor,constant: 10),

self.imageView.trailingAnchor.constraint(equalTo: self.view.trailingAnchor,constant: -10),

self.imageView.heightAnchor.constraint(equalTo: self.view.heightAnchor)])


뭐 일단 화면에 보일 정도로만 constraint를 줘볼게요. 

짜잔~~~

autoResizingMask가 무시된 것을 볼 수 있죠.

콘솔창도 보시면 아주 깨끗한 것을 볼 수 있습니다 :)




translatesAutoresizingMaskIntoConstraints의 값이 true이면(Bool타입이었죠?), 시스템은 View의 autoresizing  mask(방금 말한애)로 지정된 행동?(behavior)을 복제하는 Constraint집합을 만듭ㄴ디ㅏ.

또한 View의  frame, bounds 또는 center프로퍼티를 사용하여 View의 크기와 위치를 수정하여 auto layout에서 정적인 프레임 기반 레이아웃을 만들 수 있습니다. autoresizing mask constraint는 View의 크기와 위치를 완전히(fully specify) 지정합니다.

따라서 충들을 일으키지 않고, 이 크기 또는 위치를 수정하기 위해 추가 constraint를 추가 할 수 없습니다.

auto layout을 사용하여 View의 크기와 위치를 동적으로 계산하려면, 이 프로퍼티를 false로 설정 한 다음, View에 모호(ambiguous)하지 않고 충돌하지 않는(nonconflicting) constraint집합을 제공해야 합니다.

기본적으로 프로그래밍 방식으로 만드는 모든 View에 대해 이 프로퍼티는 true로 설정됩니다.

Interface Builder(=스토리보드)에서 View를 추가하면, 시스템은 이 프로퍼티를 false로 자동 설정합니다.



이 discussion을 다시 천천히 읽어보세요. 

이제는 조금 이해가 가실겁니다.


궁금한건, 나는 스토리보드로 View를 추가한건데 그럼 자동으로 false아닌가..?왜 명시적으로 또 false를 해줘야 하는 건지 ㅎ


아무튼 혹시나..!!! 틀린 부분이 있을지도 몰라요 ㅎㅎ.....그런 부분이 있다면 꼭 댓글이나 PC화면 오른쪽 하단에 있는 채널 서비스를 이용해서 메세지 주시면 정말 감사하겠습니다 :)

translatesAutoresizingMaskIntoConstraints를 이해하시는데 도움이 되었으면 좋겠네요 XD...



반응형