일 | 월 | 화 | 수 | 목 | 금 | 토 |
---|---|---|---|---|---|---|
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 |
- initializer
- Git
- UIKit
- struct
- Unicode
- interpace
- Xcode
- 코딩테스트
- Foundation
- String
- instance
- extension
- type
- Swift
- Method
- property
- Protocol
- tuist
- url
- Terminal
- initalizer
- 디자인패턴
- enum
- delegate
- Class
- optional
- init
- 스위프트
- IOS
- 이니셜라이저
- Today
- Total
아리의 iOS 탐구생활
[iOS/Xcode] Auto Layout에 대해 알아보자. 본문
뷰에 설정되어있는 제약조건(Constraints)을 기반으로 해서 동적으로 크기와 위치를 계산하는 것을 말한다.
사람들은 다양한 크기의 아이폰 디바이스를 사용한다. 그렇기 때문에 어플리케이션이 디바이스 사이즈에 구애받지 않고 동일한 화면을 구성할 필요가 있다.
그래서 나온 것이 오토레이아웃(Auto Layout)이다. 오토 레이아웃은 뷰의 크기와 위치를 동적으로 계산한다. 즉 인터페이스에 절대적인 좌표가 아닌 상대적인 좌표가 필요할 때 유용하다.
오토레이아웃이 주로 사용되는 이유는 외부 변경과 내부 변경 때문이다.
- 외부 변경(External Changes)
슈퍼뷰의 크기나 모양이 변경될 때 외부 변경이 발생된다. 보통 디바이스를 회전하거나 다른 크기의 클래스나 스크린을 지원하거나, 아이패드 분할 뷰(split view)를 사용할 때 발생된다.
- 내부 변경(Internal Changes)
인터페이스 뷰의 크기나 설정이 변경될 때 내부 변경이 발생된다. 보통 어플리케이션의 컨텐츠가 변경되거나 국제화를 지원하거나, 동적인 타입을 지원하는 경우이다. 예를 들어 신문 기사 어플리케이션의 경우 이미지나 텍스를 신문 기사의 레이아웃에 맞게 조정해야하는 경우를 말한다.
오토 레이아웃 속성
오토레이아웃의 속성은 정렬사각형 기반으로 한다.
속성 | 설명 |
Width | 너비 |
Height | 높이 |
Top | 정렬 사각형의 상단 |
Bottom | 정렬 사각형의 하단 |
Baseline | 텍스트의 하단 |
Leading | 텍스트 시작 |
Trailing | 텍스트 끝 |
CenterX | 수평 중심 |
CenterX | 수직 중심 |
Horizontal | 수평 |
Vertical | 수직 |
안전 영역(Safe Area)
안전 영역(Safe Area) 은 어플리케이션이 상태바, 네비게이션바, 툴바, 탭바를 가리는 것을 방지하는 영역이다. 표준 시스템이 제공하는 뷰들은 모두 안전 영역을 준수하고 있다.
제약(Constraint)
뷰 스스로 또는 뷰 사이의 관계를 속성을 통하여 정의한다. 제약은 방정식으로 나타낼 수 있다.
제약조건을 추가해주고 나서 아무거나 더블클릭해보면
위와같은 설정값들이 나오는데 이것들의 개념에 대해서도 알아보자.
먼저 First Item, Relation, Second Item 이 3개는 같이보면 좋은데, 이걸 알려면 Auto Layout이 어떻게 계산되는지를 알아야한다.
레이아웃은 일련의 선형방정식(line equations)으로 정의된다.
First Item은 지금의 View가 [안녕하세요.Ari입니다.]이고 Attribute가 Top이다.
Relation은 Equal이고 (위 식에서 Relationship이라고 해놓은 것)
Second Item은 Safe Area이고, Attribute는 Top이다.
Constant는 190이다.
여기서는 Attribute가 Top이었지만 이 외에도 bottom, leading, trailing 이렇게 총 4가지가 있겠다.
🔍 예제
만약 4방향 모두 제약조건을 임의로 추가해주었는데 위와 같이 텍스트가 짤리는 현상이 생겼다고 가정하자.
여기서 Relation을 이용해주면 편하다. Relation을 Equal가 아니라 Less than or Equal로 바꾸어지게 된다면 아까 선형방정식에서 아래와 같이 부등호를 넣어준다고 생각하면 된다.
작거나 같음(Less than or Equal)
Safe Area.trailing ≤ 안녕하세요. Ari입니다..trailing + 160
같음(Equal)
Safe Area.trailing = 안녕하세요. Ari입니다..trailing + 160
크거나 같음(Greater than or Equal)
Safe Area.trailing ≥ View.trailing + 68
Priority
- 고유 콘텐츠 크기(Intrinsic Content Size)
뷰가 원래 가지고 있었던 크기를 고유 콘텐츠 크기(Intrinsic Content Size)라고 한다. 즉 오토레이아웃에 의해 변경되기 전 원본 크기를 의미한다.
- 제약 우선도(Constant Priority)
오토레이아웃에서 제약이 가지는 우선도를 말한다. 만약 제약이 충돌하는 경우, 우선도가 높은 제약부터 레이아웃에 적용된다. 고유 콘텐츠 크기보다 뷰가 커지지 않도록 제한하는 콘텐츠 허깅 우선도(Contents Hugging Priority) 와, 이와 반대로 작아지지 않도록 제한하는 콘텐츠 축소 방지 우선도(Contents Compression Resistance Priority) 가 있다.
Priority값은 기본적으로 1000으로 설정되고 값이 클수록 우선순위가 높다고 보면 된다.
840 이런 값도 넣을 수 있긴 하지만 필수(1000), 높음(750), 중간(500), 낮음(250)을 사용하길 권장한다.
🔍 예제
아래 사진처럼 Constraint를 2개를 준다면 Xcode는 어느것을 적용시켜야 할지 몰라서 에러를 내게 된다.
그 이유는 두 Constraint의 Priority가 같기 때문이다.
해결 방법은 2개중 하나의 Priority를 낮게 주면 된다.
Mutiplier
Constraint가 양수라는 가정하에 일단 Mutiplier가 커지면 커질수록 등호를 가운데로 한 양쪽 항의 값이 커진다고 보면 된다.
이렇게 위와 같이 Equal Widths를 준 상태에서 Width Constraint를 누르고 Multiplier를 수정해보면…
위와 같은 결과물을 확인할 수 있다.
여기서 Multiplier가 2라고 가정한다면
blueView.Width = 2 * yellowView.Width
가 되고, 이 말은 파란View의 너비는 노란View의 너비의 2배라고 보면 되겠다.
이게 그냥 Multiplier의 역할이다.
- Reverse Multiplier
위 예제로 설명하자면 파란 뷰가 더 비율이 컸다면 거꾸로 노란뷰가 커지게 됨.
- Convert To Decimal
밑에 Presets처럼 비율로 나와있는 걸 십진수로 바꿔준다.
(4:3 이라면 1.333333 으로 바꿔줌)
- Presets
많이 쓰는 비율.
🔍 오토 레이아웃 설정 예제
프로젝트를 생성후 Main.storyboard에서 Label을 하나 추가해준다.
iPhone 11 크기인데, 가운데에 맞춰서 위치를 설정해주었다.
그러나 여기서 작은 사이즈로 크기를 변경하게 된다면…
이렇게 Label의 위치가 가운데가 아닌 것을 확인할 수 있다.
그 이유는 디바이스에 따라서 화면 크기는 변경되었는데, 정작 Label의 포지션이 일정하기 때문에 위지가 다른 문제가 발생하는 것이다. 이런 문제를 해결하기 위해 Auto Layout을 아래와 같이 활용해보자.
먼저 Label을 선택하고 스토리보드 편집 하단에서 Add New Alignment Constraints를 선택 후,
Horizontally in container를 선택하고 Add Constraint를 클릭해준다.
그러나 아직 Y position이 해결되지 않아서 아래와 같은 붉은 경고마크가 나온다.
Horizontally in container는 Parent View의 Center X 값을 기준으로 선택한 View의 Center X값을 정의하는 것이다.
아까 체크할때 value를 0으로 설정했기 때문에 지금은 parent View의 Center X와 label의 Center X가 일치하는 상태일 것이다.
그렇다면 Y position 해결은 어떻게 해야할까?
아까 Constraint를 추가해줄 때 Horizontally in container 아래에 위치해있던 Vertically in Container를 선택해서 상위뷰의 Center Y값 기준을 맞추는 것도 방법이겠고, 특정 위치를 기준으로 잡는 것도 가능하다.
아래는 상위뷰의 Top 기준으로 위치를 잡는 방법이다.
Add New Alignment Constraints를 다시 선택하면 위와 같이 Top, Bottom, Width, Height 속성 값들이 자동으로 표기되어있는데, 어두운 빨강색 부분을 클릭해주면 빨강색으로 색이 밝혀지면서 Add Constraint를 할 수 있게 상태가 바뀐다.
Add를 하게되면 스토리보드가 아래와 같이 표시된다.
문제가 되었던 Missing Constraints도 해결이 되었다. 다시 디바이스 크기를 이리저리 바꾸어도 Label의 위치는 X좌표는 가운데 정렬, Y는 상위뷰의 top과 label의 간격이 80인 상태로 표시가 되는 것을 확인할 수 있다.
다른 View 기준 Auto Layout 사용하기
이전에 생성하고 위치를 잡은 Label 기준으로 새로운 UIView의 위치를 정해보자.
먼저 View를 추가하고 백그라운드 컬러를 원하는 색상으로 수정한다. 이 상태로 Run을 하면…
위 캡쳐와 같이 위치가 원하는 곳에 나오지 않는다. Auto Layout을 이용하고 원하는 위치로 설정해보자.
먼저 Label에 대해서 Vertical Spacing, 상위 View에 대해서 Align Trailing을 설정해준다.
그러나 아직도 제약조건이 더 필요하다고 경고가 나온다.
위와 같이 너비와 높이의 제약조건을 설정해주면 된다.
아래와 같이 스토리보드에서 Control + Drag 를 이용하여 추가해주는 방법과
아니면 스토리보드 하단에 있는 Add New Alignment Constraints를 이용하여 설정해줄 수도 있다.
레이어 두개를 Shift키를 눌러 함께 설정해주면 Leading Edges를 설정해줄 수도 있다.
제약조건 최종
Reference
'Swift > iOS' 카테고리의 다른 글
[iOS] local에 있는 오디오파일 재생하는 방법 (0) | 2021.09.28 |
---|---|
[iOS] Bundle이 뭘까? (0) | 2021.09.28 |
[Swift/iOS] FileManager로 파일 생성(쓰기), 읽기, 삭제하기 (3) | 2021.08.27 |
[Swift] 시간과 날짜를 다루는 타입에 대해서 알아보자. (0) | 2021.08.25 |
[Swift/iOS] Codable로 JSON을 파싱해보자. (0) | 2021.08.22 |