티스토리 뷰
Understanding Auto Layout
공식문서에서 말하는 오토레이아웃🔲이란,
constraints(뷰에 주는 제약? 뷰에주는 명령? 뷰에 주는 조건?)를 기반으로
뷰의 크기와 위치를 동적으로 계산해주는 것이라고 합니다!
기존에는 frame
을 이용하여 view의 절대적인 길이를 조절했었는데요,
아이폰 기기가 다양해지면서 오토레이아웃을 이용하여 상대적인 위치값을 찾아서 스스로 배치시키도록 만들어 준 것이죠🎯
Anatomy of a Constraint
Attributes
Attributes
는 오토레이아웃을 위해, constraints
를 계산하기 위해 사용되는 요소를 말해요!
이는, size attributes(Height, Width)와 location attributes(Leading, Left, Top)로 나뉘어요
- Leading: (미국기준)글자가 시작하는 부분입니다. 따라서 왼쪽을 뜻하죠
- Trailing: (미국기준)글자가 끝나는 부분입니다. 따라서 오른쪽을 뜻하죠
- Baseline: 글자가 닿는 부분이에요. 보통 글자는 뷰의 아예 밑바닥이 아니고, 조금 떠있잖아요? 그 기준선을 뜻하는 것이죠
Sample Equations
Attributes(size, location)들은 다음과 같은 특징들을 가져요
- You cannot constrain a size attribute to a location attribute.
(둘은 함께쓰일 수 없어요) - You cannot assign constant values to location attributes.
(location에는 상수값을 할당할 수 없어요: 기준이 되는 view가 있어야한다는 뜻이죠!) - You cannot use a nonidentity multiplier (a value other than 1.0) with location attributes.
(location에서는 multiplier로 1.0이 아닌 값을 사용할 수 없어요: 아래 사진을 보면 multiplier가 뭔지 알거에요!) - For location attributes, you cannot constrain vertical attributes to horizontal attributes.
(vertical attributes과 horizontal attribute는 서로에게 제약을 걸 수 없어요) - For location attributes, you cannot constrain Leading or Trailing attributes to Left or Right attributes.
(Leading을 상대 뷰의 왼쪽 속성에, Trailing을 상대 뷰의 오른쪽 속성에 제약을 걸 수 없어요)
위의 사진은 빨간색 뷰의 Leading의 위치를 정해주는 과정이에요
해석하면, 빨간색 뷰의 Leading의 위치 = multiplier x 파란색 뷰의 Trailing의 위치 + 8포인트
즉, 8포인트만큼 떨어진 곳에 위치시킨다는 뜻이죠!
좀 더 영어를 읽어봅시다..🤮
(영어 범벅글은, 항상 마음만 먹으면 극복할 수 있는거 같아요! 시작이 반인거죠😂)
// Setting a constant height
// 길이를 나타내야 하니까, multiplier가 0이 되는군요!
View.height = 0.0 * NotAnAttribute + 40.0
// Setting a fixed distance between two buttons
// 8포인트만큼 떨어져 있다는 뜻이네요!
Button_2.leading = 1.0 * Button_1.trailing + 8.0
// Aligning the leading edge of two buttons
// leading끼리 식을 이루네요? 이는 정렬을 의미해요! 서로의 시작점을 맞추겠다는 뜻이죠
Button_1.leading = 1.0 * Button_2.leading + 0.0
// Give two buttons the same width
// 두 버튼의 너비가 같다는 뜻이에요!
Button_1.width = 1.0 * Button_2.width + 0.0
// Center a view in its superview
// superview(상위 뷰)의 한 가운데에 위치하겠죠?
View.centerX = 1.0 * Superview.centerX + 0.0
View.centerY = 1.0 * Superview.centerY + 0.0
// Give a view a constant aspect ratio
// 높이와 너비의 비율을 설정하고있네요!
View.height = 2.0 * View.width + 0.0
위의 "="기호는, 프로그래밍에서 사용하는 "할당"의 뜻이 아니에요!
수학적인 "등호"를 나타내기 때문에, 좌항과 우항의 값이 다르면 스토리보드의 빨간줄이 나타나게 되는 것이에요!
따라서, 우리는 그 빨간줄을 만나게 되면 해당 등호관계가 어긋낫다는 것을 알 수 있게되는 것이죠😲
Creating Nonambiguous Layouts
애매모호한(?)레이아웃을 구성하지 않기 위해서는, 뷰에게 명확한 위치를 지시해야겠죠?
다음 사진은 superview에 대해, 가운데에 뷰를 위치시키는 3가지 경우에요
- superview로부터 떨어진 Leading값과 view의 너비를 아는 경우
- superview로부터 떨어진 Leading값과 Trailing값을 아는 경우
- x축을 가운데정렬하고, superview로부터 떨어진 Leading값을 아는 경우
즉, 시작 위치와 너비만 알 수 있으면 명확한 위치를 나타낼 수 있다는 뜻인거죠!!
하지만 어떻게 표현할건지에 따라 다르기때문에, 해당 위치를 나타내는 여러가지 방법중 어떤 방법을 선택할지 고민해봐야해요
예를들어, 위의 사진처럼 나타내고 싶어요.
그럼 아래의 사항을 고려해봐야 해요!
// Vertical Constraints
Red.top = 1.0 * Superview.top + 20.0
Superview.bottom = 1.0 * Red.bottom + 20.0
Blue.top = 1.0 * Superview.top + 20.0
Superview.bottom = 1.0 * Blue.bottom + 20.0
// Horizontal Constraints
Red.leading = 1.0 * Superview.leading + 20.0
Blue.leading = 1.0 * Red.trailing + 8.0
Superview.trailing = 1.0 * Blue.trailing + 20.0
Red.width = 1.0 * Blue.width + 0.0
또는, 아래처럼 다른 방법으로도 표현해낼 수 있어요!
// Vertical Constraints
Red.top = 1.0 * Superview.top + 20.0
Superview.bottom = 1.0 * Red.bottom + 20.0
Red.top = 1.0 * Blue.top + 0.0
Red.bottom = 1.0 * Blue.bottom + 0.0
//Horizontal Constraints
Red.leading = 1.0 * Superview.leading + 20.0
Blue.leading = 1.0 * Red.trailing + 8.0
Superview.trailing = 1.0 * Blue.trailing + 20.0
Red.width = 1.0 * Blue.width + 0.0
각 상황별로 어떤 장단점이 있고,
내가 적용하려는 뷰에는 어떤 방법이 더 효율적인지 생각해보는게 중요해요!
(항상 어떤 방법만이 정답이 되는건 아니라는 뜻이에요⚠️)
Constraint Priorities
Constraint Inequalities
오토레이아웃의 Constraint는 항상 등호관계만 성립되는건 아니에요
말 그대로, 부등호 관계가 성립할 수도 있죠.
// Setting the minimum width
View.width >= 0.0 * NotAnAttribute + 40.0
// Setting the maximum width
View.width <= 0.0 * NotAnAttribute + 280.0
위와같이, 최소값 혹은 최대값을 지정하여, super view의 사이즈에 따라 달라지는 크기로 설정할 수도 있어요!
Constraint Priorities
제약의 우선도(Priorities)는 왜 필요할까요??🤔
Constraint는 중복으로 추가할 수 있어요
그리고, Constraint의 우선도에 따라 제약이 적용되게 할 수 있죠.
(그렇기 때문에, 우선도를 같게해서는 안돼요!)
우선도는 0 ~ 1000까지 나뉘며, default는 1000이에요
그럼 어떤 경우에 쓰일 수 있을까요?
어떤 view를 만든다고 합시다. (우리는 가로길이에 대해서만 생각해 볼거에요)
- view를 만들고 싶어요
- 이 view의 가로길이는 100을 넘기지 않아요. 이 제약은 우선순위가 750이에요!
이 경우에는 가로의 길이를 명확하게 파악하기가 힘들어요
하지만 다음의 경우는 어떨까요?
- view를 만들고 싶어요
- 이 view의 가로길이는 100을 넘기지 않아요. 이 제약은 우선순위가 750이에요!
- 이 view의 가로길이는 20이에요. 이 제약은 우선순위가 250이에요!
우선순위가 낮은 조건이지만, 명확한 길이가 나오게 되죠?
view의 가로길이는 추후에 추가될 제약에 의해 변할 수 있지만,
default값은 20이 될거에요!
Intrinsic Content Size
우리가 값을 정해주지 않아도, 스스로 크기를 조절하는 친구가 있어요.
View | Intrinsic content size |
---|---|
UIView and NSView | No intrinsic content size. |
Sliders | Defines only the width (iOS). |
Labels, buttons, switches, and text fields | Defines both the height and the width. |
Text views and image views | Intrinsic content size can vary. |
Labels, buttons, switches, text fields와 같은 친구들이 해당한다고 해요
(Slider는 너비만 해당한다고 하는군요!)
이들 컨텐츠 안에 크기를 유추해줄 수 있는 Intrinsic 컨텐츠가 있기 때문이에요!
예를들어, Label은 해당 view안에 Intrinsic 컨텐츠인 텍스트가 들어가기 때문에
텍스트 크기에 따라 전체 컨텐츠의 크기가 자동으로 조절되는거에요!
CHCR
content hugging이라는 힘이 있어요. 이 힘은, Intrinsic Content에 맞게 외부에서 가해지는 힘이에요!
그리고, content compression이라는 힘이 있어요. 이 힘은, Intrinsic Content에 맞게 내부에서 가해지는 힘이에요!
포인트는 ✅Intrinsic Content와 관련된 힘이라는 거에요..!!
위의 사진을 보면, content compression이 content hugging에대한 반발력으로만 보면 안된다는 것이죠!
(사실, 어느정도 맞는 말이기는 해요..!)
이러한 두 힘을 CHCR이라고 표기하기도 한답니다✔️
// Compression Resistance
View.height >= 0.0 * NotAnAttribute + IntrinsicHeight
View.width >= 0.0 * NotAnAttribute + IntrinsicWidth
// Content Hugging
View.height <= 0.0 * NotAnAttribute + IntrinsicHeight
View.width <= 0.0 * NotAnAttribute + IntrinsicWidth
이 두가지 힘에 content priority를 활용하면
Intrinsic Content를 가지는 콘텐츠가 여러개 있을 때, 우선순위(priority를)에 따라 크기를 조절해줄 수 있어요
예를들어 3개의 Label이 있고, 각자의 우선순위에 따라 3개의 Label길이가 조절될 수 있는거에요!
여기까지!! 오토레이아웃의 기초적인 부분을 정리해 보았어요!
iOS에서 무조건!!! 알아야하는 개념인 만큼 꼼꼼 가득히 적었습니다😅
정말정말 중요한 개념이니까, 여러분도 빈틈없이 정리해두셔야 해요!!
이해가 안되는 부분이나, 틀린 부분이 있으면 코멘트를 남겨주세요!
피드백은 정말정말 환영입니다🎉🎉
Reference
'iOS' 카테고리의 다른 글
The compiler is unable to type-check this expression in reasonable time (0) | 2021.10.17 |
---|---|
Table View (0) | 2021.05.23 |
URLSession API (0) | 2021.01.28 |
GCD (0) | 2021.01.27 |
Concurrency (0) | 2021.01.27 |