티스토리 뷰

iOS

Auto Layout - Anatomy of a Constraint

강경 2021. 6. 19. 12:17
728x90
반응형

Understanding Auto Layout

공식문서에서 말하는 오토레이아웃🔲이란,
constraints(뷰에 주는 제약? 뷰에주는 명령? 뷰에 주는 조건?)를 기반으로
뷰의 크기와 위치를 동적으로 계산해주는 것이라고 합니다!
기존에는 frame을 이용하여 view의 절대적인 길이를 조절했었는데요,
아이폰 기기가 다양해지면서 오토레이아웃을 이용하여 상대적인 위치값을 찾아서 스스로 배치시키도록 만들어 준 것이죠🎯

Anatomy of a Constraint

Attributes

Attributes는 오토레이아웃을 위해, constraints를 계산하기 위해 사용되는 요소를 말해요!
이는, size attributes(Height, Width)와 location attributes(Leading, Left, Top)로 나뉘어요

image1

  • 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을 상대 뷰의 오른쪽 속성에 제약을 걸 수 없어요)

image2

위의 사진은 빨간색 뷰의 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가지 경우에요

image3

  1. superview로부터 떨어진 Leading값과 view의 너비를 아는 경우
  2. superview로부터 떨어진 Leading값과 Trailing값을 아는 경우
  3. x축을 가운데정렬하고, superview로부터 떨어진 Leading값을 아는 경우

즉, 시작 위치너비만 알 수 있으면 명확한 위치를 나타낼 수 있다는 뜻인거죠!!
하지만 어떻게 표현할건지에 따라 다르기때문에, 해당 위치를 나타내는 여러가지 방법중 어떤 방법을 선택할지 고민해봐야해요

image4

예를들어, 위의 사진처럼 나타내고 싶어요.
그럼 아래의 사항을 고려해봐야 해요!

image5

// 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

또는, 아래처럼 다른 방법으로도 표현해낼 수 있어요!

image6

// 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

image7

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

야곰닷넷 - 오토레이아웃 정복하기
Apple 공식문서 - Auto Layout Guide

728x90
반응형

'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