[iOS] AutoLayout 기본개념(1)

Youngwoo Lee·2021년 4월 23일
0

iOS

목록 보기
7/46
post-thumbnail

야곰의 오토레이아웃 정복하기 강의를 듣고 느낀 점들을 정리하는 시간을 가져보자!!!
참고 : Apple developer AutoLayout Guide

AutoLayout에 대한 이해

오토레이아웃은 크기와 위치를 Constraint를 기반으로 동적으로 계산하는 개념이다

이러한 Constraint는 뷰의 내부적 변경과 외부적 변경에 대응하기 위한 제한을 의미하는 것이다

External Changes

  • OS X에서 window 크기를 사용자가 조절하는 경우
  • iPad에서 Split View를 이용하여 앱을 이용하는 경우
  • iOS 기기의 방향을 회전시키는 경우
  • iOS 기기를 통해 전화, 오디오 녹음 등을 이용함으로써 상단 바가 나타나는 경우
  • 이외

Internal Changes

  • 앱 내의 Control을 통해서 (버튼 클릭, View 위치 변경) contents에 변화가 생기는 경우
  • 앱이 Dynamic Type을 지원하는 경우 (Accessibility와 관련)


Auto Layout vs Frame-Based Layout

오토레이아웃이 있기 이전에는 상수 값을 통해서 Device의 화면에 대응되는 View들의 위치와 크기를 정해주었다

하지만, 이러한 작업은 점점 많아지는 기기들과 변화들에 모두 대응하기에 힘들기 때문에 AutoLayout을 개발하여 이 모든 상황들에 쉽게 대응하고자 하였다

자, 이렇게 우리가 왜 AutoLayout에 대해서 학습하고 사용해야되는지 알아보았으니 이제 사용하는 방법에 대해서 알아보자!!



Constraint 파헤쳐보기

위에서 자주 나오는 단어인 Constraint에 대해서 알아보자!
개인적으로 AutoLayout을 잘 하는 것은 Constraint에 대한 이해도가 높다고 하는 것과 같은 것이라고 생각한다.


쉽게 말해서 Constraint는 뷰들 간의 관계를 맺어주는 것이다
아래 그림을 보면 수식을 통해서 뷰들 간의 관계를 맺어주는 것을 볼 수 있다

코드로 Constraint를 정의할 경우 위 수식을 이해하고 있으면 보다 쉽게 사용할 수 있으니 반드시 숙지!!!!!

y = mx + c

이 중에서 가장 모호한 개념일 수 있는 Attribute에 대해서 표현하자면, Item으로 표현되는 View들의 속성을 말하는 것이다!

Attribute : View의 위치(Top, Leading, Trailing, Bottom 등등...), 혹은 크기를 나타내는 속성(Width, Height)이 있다

더 자세한 것들은 NSLayoutAttribute 배열을 통해서 볼 수 있다!!

아 그리고 이러한 Constraint에는 몇몇의 간단한 규칙이 있는데, 한 번 보고 이해하자

  • 위치 Attribute와 크기 Attribute를 동시에 사용하면서 Constraint를 정의할 수 없다
  • 위치 Attribute에는 상수를 할당 할 수 없다(?)
  • 수직과 수평 attribute는 서로 같이 사용할 수 없다
  • leading, Trailing Attribute는 left, right Attribute와 같이 사용할 수 없다. 하나로 통일해서 사용하자!!

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가 발생하니 논리적 계산을 잘 하자!!!


명확하게 Constraint 부여하기

우리는 동적으로 View의 크기와 위치를 주기 위해서 AutoLayout을 사용하는데, 개발자가 만약에 애매하게, 만족하지 못하는 Constraint를 부여하는 경우, View의 모양이 망가진다

우리가 AutoLayout을 줄 때 명심해야 되는 점은 넓이, 높이 모두 아래와 같다

  • 시작점, 크기
  • 시작점, 마무리되는 지점

이 처럼 되면 View는 자신의 위치와 크기를 모호하지 않게 알 수 있다

그리고 위에서 보듯이 AutoLayout에는 정답이 정해져 있는 것이 아니다

논리적으로 모호하지 않게 Constraint 를 부여하는 것이라면 모두 허용된다


Constraint Inequalities(부등호를 통한 Constraint)

//Setting Minimum Width
View.width >= 0.0 * NotAnAttribute + 40.0

//Setting Maximum Width
View.width <= 0.0 * NotAnAttribute + 280.0

꼭 등호가 아니여도 최대, 최소 값 설정을 통해서 관계를 정할 수 있다


Constraint Priorities(Constraint 우선순위)

여러 Device, 여러 상황에 대하여 우리는 한 화면에서 Constraint를 부여해야되는데, 이럴 경우 Priority를 통해서 각 하면에 어떻게 대응해야되는지 설정할 수 있다

Priority가 낮은 Constraint는 비교적 Priority가 높은 것과 대적하는 경우가 생기면 Constraint를 상실(?) 하게 된다

우리는 항상 1000의 우선도를 사용할 필요가 없으며, default로 정해져 있는 (low = 250) (high = 750) 을 제외하고 1~1000 사이의 수를 모두 사용할 수 있다



Intrinsic Content Size(고유 컨텐츠 사이즈)

우리가 사용하는 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 하고 앱 실행을 하면 이상하게 나타날테니ㅎㅎ...

반드시 다른 방법을 통해서 해결하고 넘어가길!!!!!


CHCR(Content hugging, Compression Resistance)

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 prioritydefault high로 줄 경우

오른쪽 Label 혼자 content hugging priority가 낮기 때문에 Content Size에 맞게 View의 크기를 유지하는 힘을 잃게 되어 아래 처럼 커지게 된다!!

반면, Compression Resistance는 다르다

Compression Resistanceleft < mid < right 로 부여할 경우

Label 내의 Content 크기가 크다고 가정할 때,

Compression Resistance가 큰 View의 경우는 내용이 잘리지 않는 것을 볼 수 있다

이 처럼, Compression ResistanceContents Hugging은 상반된 개념은 아니다. 다른 상황에서 적용되는 개념이기에 잘 이해하고 적절한 상황에서 사용하자!!!



To be Continue....

profile
iOS Developer Student

0개의 댓글