야곰의 오토레이아웃 정복하기 강의를 듣고 느낀 점들을 정리하는 시간을 가져보자!!!
참고 : Apple developer AutoLayout Guide
오토레이아웃은 크기와 위치를 Constraint를 기반으로 동적으로 계산하는 개념이다
이러한 Constraint는 뷰의 내부적 변경과 외부적 변경에 대응하기 위한 제한을 의미하는 것이다
오토레이아웃이 있기 이전에는 상수 값을 통해서 Device의 화면에 대응되는 View들의 위치와 크기를 정해주었다
하지만, 이러한 작업은 점점 많아지는 기기들과 변화들에 모두 대응하기에 힘들기 때문에 AutoLayout을 개발하여 이 모든 상황들에 쉽게 대응하고자 하였다
자, 이렇게 우리가 왜 AutoLayout에 대해서 학습하고 사용해야되는지 알아보았으니 이제 사용하는 방법에 대해서 알아보자!!
위에서 자주 나오는 단어인 Constraint
에 대해서 알아보자!
개인적으로 AutoLayout을 잘 하는 것은 Constraint
에 대한 이해도가 높다고 하는 것과 같은 것이라고 생각한다.
쉽게 말해서 Constraint
는 뷰들 간의 관계를 맺어주는 것이다
아래 그림을 보면 수식을 통해서 뷰들 간의 관계를 맺어주는 것을 볼 수 있다
코드로 Constraint를 정의할 경우 위 수식을 이해하고 있으면 보다 쉽게 사용할 수 있으니 반드시 숙지!!!!!
y = mx + c
이 중에서 가장 모호한 개념일 수 있는 Attribute
에 대해서 표현하자면, Item
으로 표현되는 View
들의 속성을 말하는 것이다!
Attribute : View의 위치(Top, Leading, Trailing, Bottom 등등...), 혹은 크기를 나타내는 속성(Width, Height)이 있다
더 자세한 것들은
NSLayoutAttribute
배열을 통해서 볼 수 있다!!
아 그리고 이러한 Constraint에는 몇몇의 간단한 규칙이 있는데, 한 번 보고 이해하자
2번째꺼 빼고는 전부 이해가 되는듯(?)
위치의 경우 비교 대상과 상수를 통해서 위치를 명시해야되는데, 단순하게 상수로만 할당할 수 없다
코드로 Constraint를 작성할 경우
// Setting a fixed distance between two buttons
Button_1.trailing = 1.0 * Button_2.leading - 8.0
// Aligning the leading edge of two buttons
Button_2.leading = 1.0 * Button_1.leading + 0.0
// Give two buttons the same width
Button_2.width = 1.0 * Button.width + 0.0
// Center a view in its superview
Superview.centerX = 1.0 * View.centerX + 0.0
Superview.centerY = 1.0 * View.centerY + 0.0
// Give a view a constant aspect ratio
View.width = 0.5 * View.height + 0.0
여기 코드에 나와 있는 =
는 할당의 뜻이 아니다!!! 같다
라는 뜻임을 명심하자!!
등호가 성립하지 않는 조건에서는 Error가 발생하니 논리적 계산을 잘 하자!!!
우리는 동적으로 View의 크기와 위치를 주기 위해서 AutoLayout을 사용하는데, 개발자가 만약에 애매하게, 만족하지 못하는 Constraint를 부여하는 경우, View의 모양이 망가진다
우리가 AutoLayout
을 줄 때 명심해야 되는 점은 넓이, 높이 모두 아래와 같다
이 처럼 되면 View는 자신의 위치와 크기를 모호하지 않게 알 수 있다
그리고 위에서 보듯이 AutoLayout
에는 정답이 정해져 있는 것이 아니다
논리적으로 모호하지 않게 Constraint
를 부여하는 것이라면 모두 허용된다
//Setting Minimum Width
View.width >= 0.0 * NotAnAttribute + 40.0
//Setting Maximum Width
View.width <= 0.0 * NotAnAttribute + 280.0
꼭 등호가 아니여도 최대, 최소 값 설정을 통해서 관계를 정할 수 있다
여러 Device, 여러 상황에 대하여 우리는 한 화면에서 Constraint를 부여해야되는데, 이럴 경우 Priority를 통해서 각 하면에 어떻게 대응해야되는지 설정할 수 있다
Priority가 낮은 Constraint는 비교적 Priority가 높은 것과 대적하는 경우가 생기면 Constraint를 상실(?) 하게 된다
우리는 항상 1000의 우선도를 사용할 필요가 없으며, default로 정해져 있는 (low = 250) (high = 750) 을 제외하고 1~1000 사이의 수를 모두 사용할 수 있다
우리가 사용하는 View들 중에는 우리가 굳이 사이즈를 정해주지 않아도, View 안에 들어가는 내용물에 따라서 스스로 View의 크기를 정의하는 View들이 있다
아래 표를 보면,
UIView/NSView 의 경우는 안에 어떤 내용이 들어갈 지 모르기에 고유 컨텐츠 사이즈가 적용되지 않는다. 그래서 우리는 UIView 객체를 사용하기 위해서는 크기에 대한 Constraint를 부여해주어야 한다.
But,
Labels, Button 의 경우 안에 들어오는 내용물에 따라서 스스로 높이와 넓이를 정의해 준다.
하지만,
UIView 와 같은 intrinsic Content size가 없는 개체에도 intrinsic Content size를 부여할 수 있는 방법이 있다
UIView 를 커스터마이징하는 View Class를 만들고 intrinsicContentSize 프로퍼티 값을 오버라이드 해주면 된다
그렇게 되면 위와 같이 width, height
를 정의하지 않아서 에러가 발생하는 View를
고유 사이즈를 통해서 AutoLayout을 만족시켜줄 수 있다
추가적으로
Storyboard
에서 instrinsic ContentSize
를 가지고 있다고 눈속임시켜 줄 수도 있는데,
placeholder
값이 그 방법이다!!
하지만 이는 storyboard
에서만 그렇게 보이는 것이지, 실제로는 넓이, 높이 값에 대한 값을 해결해준 것은 아니므로 Build 하고 앱 실행을 하면 이상하게 나타날테니ㅎㅎ...
반드시 다른 방법을 통해서 해결하고 넘어가길!!!!!
Compression Resistance - 외부에서 View의 Content를 찍어 누르려고 할 때, 버티는 힘을 의미 (잘리지 않도록 버티는 힘)
Content Hugging - Content Size에 맞게 줄어들려고 하는 힘 (정확히 Content Size에 맞게 View를 조절하려고 하는 힘)
이 두 개념이 상반되는 개념이 아니라는 것을 명심해야된다!!!!
CHCR, CRCH 는 Priority를 적절하게 사용해서 View에 부여한다
일단 예제를 통해서 개념을 이해해보자!!
세 개의 Label에 모두에 superView
와 20만큼의 거리, 왼쪽 오른쪽 Label에 20만큼의 제약을 준 상태에서
intrinsic Content Size 때문에 width
가 고정된 상태에서 위치를 못 잡는 것을 볼 수 있다
이 때, 왼쪽 두 Label의 content hugging priority
를 default high
로 줄 경우
오른쪽 Label 혼자 content hugging priority
가 낮기 때문에 Content Size에 맞게 View의 크기를 유지하는 힘을 잃게 되어 아래 처럼 커지게 된다!!
반면, Compression Resistance
는 다르다
Compression Resistance
를 left < mid < right
로 부여할 경우
Label 내의 Content 크기가 크다고 가정할 때,
Compression Resistance
가 큰 View의 경우는 내용이 잘리지 않는 것을 볼 수 있다
이 처럼, Compression Resistance
와 Contents Hugging
은 상반된 개념은 아니다. 다른 상황에서 적용되는 개념이기에 잘 이해하고 적절한 상황에서 사용하자!!!
To be Continue....