Featured image of post Auto Layout(1)

Auto Layout(1)

Understanding Auto Layout

Auto Layout dynamically calculates the size and position of all the views in your view hierarchy, based on constraints placed on those views.

오토 레이아웃은 뷰에 배치된 제약조건(constraints)에 따라 뷰의 크기와 위치를 동적으로 계산해 준다.

External Changes 외부 조건의 변화

  • 사용자가 윈도우 사이즈 조절(Mac OS X)
  • iPad의 스플릿 뷰(Split View)를 나가거나 들어오는 경우(iOS)
  • iOS 기기 로테이트➡️스크린 뱡향 변경(iOS)
  • active call / recording bar가 나타나거나 사라지는 경우(iOS)

Internal Changes 내부적 요인의 변화

  • 앱 내부에서 콘텐츠 뷰 사이즈 변경
  • 앱이 Dynamic Type 지원하는 경우

Anatomy of a Constraint

img 빨간뷰의 머리(Leading)은 파란뷰의 오른쪽 끝(Trailing) + 8 포인트만큼에 위치한다.

Attribute

img

  • 크기 Attribute: Width, Height

  • 위치 Attribure: Top, Bottom, Leading(Left), Trailing(Right), Center X/Y, Baseline(글자의 밑바닥)

  • Not An Attribue

    ❗️ Attribute 사용 Rule:

    • 크기 attribue와 위치 attribute를 섞어서 사용 불가능
    • 위치 attribute에 상수 할당 불가(기준이 없기 때문에)

Creating Nonambigouos, Statisfiable Layout (모호하지 않은 레이아웃 생성 - 명확하게 지시하기)

img

x축에 한해 1,2,3 모두 계산 가능 superView에서 얼마만큼 떨어져 있는지, 너비를 알려주면 된다.

가로, 세로화면에서 반씩 차지하는 두개의 view 구성해 보기

img

  1. 두개의 뷰 생성 후 위, 아래 20 포인트씩 제약을 설정한다
  2. 좌, 우 20 포인트씩 제약을 설정한다
  3. storyboard에서 에러가 발생하는데 왜지? (좌우 여백을 주었어도 컴퓨터는 사이즈를 알 수 없다)
  4. 두개의 뷰를 동시에 선택하고 Equal Width를 선택한다

img

다른 방법으로는

  1. 빨간색 뷰를 사방으로 20 포인트씩 제약을 설정한다
  2. 파른 뷰도 오른쪽으로 20 포인트 제약을 주고, 두개의 뷰를 동시에 선택한 후 Equal Width를 선택한다
  3. 두개의 뷰를 동시에 선택하고 Align 버튼을 클릭하여 Top Edges / Bottom Edges를 선택하고 add constraints해 준다

Constraint Priorities

<= or >= 연산자를 사용하여 최소 최대 크기를 지정할 수 있다.
ex> 40 <= width >= 280

다른 뷰가 먼저 자리잡고 난 이후에 최소값과 최대값 사이의 크기로 자리잡는다.

제약의 우선도(priority)가 달라질 수 있다. 우선도는 제약이 뷰에 가해지는 힘이라고 볼 수 있는데, 여러개의 제약이 존재하는 경우 우선도가 낮은 제약은 무시될 수 있다.

1~1000까지의 우선도가 있고 높을수록 우선시된다. (기본값은 1000)

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

컨텐츠의 사이즈를 기반으로 뷰의 사이즈를 정할 수 있다.(텍스트 길이에 따라 버튼의 사이즈가 정해진다)

img

❗️ Slider의 설명 Defines only the width (iOS)는 오류 - Defines only **height

text view의 경우 스크롤이 활성화 되어있으면 컨텐츠 사이즈가 정해지지 않고, 스크롤이 비활성화 되어있으면 텍스트 길이에 따라 컨텐츠 사이즈가 정해진다.

Veiw에 Instrinsic size가 없는 경우 코드를 이용해 사이즈를 정해줄 수 있다. 아래의 코드를 작성하고 view의 identity inspector에서 class명을 myView로 설정해주면 50 x 50의 사이즈를 갖게 설정할 수 있다.

1
2
3
4
5
6
@IBDesignable
class myView: UIView {
    override var intrinsicContentSize: CGSize {
        return CGSize(width: 50, height: 50)
    }
}

CHCR (Content-Hugging equations and Compression-Resistance)

  • Compression-Resistance:

    • 외부에서 뷰에 압력이 있을때 줄어들지 않으려고 컨텐츠가 버티려는 힘(가로, 세로)
  • Content-Hugging:

    • 컨텐츠 사이즈에 맞게 fit하게 맞도록 줄어드는 힘(늘어나지 않으려고하는 힘)
  • 기준이 되는 것은 Instrinsic Content Size이며 CR과 CH 는 priority(우선순위)를 가지고 적용된다.

img

3개의 레이블을 만들고 각각 20씩 왼쪽과 오른쪽에 constraint를 설정해 주었다. 레이블의 사이즈가 변해야 하는 경우 Content-Hugging을 1000으로 설정한 첫번째 레이블은 늘어나지 않고, 750으로 설정한 두번째 레이블도 변함이 없고 priority 기본값인 251을 가지고 있는 세번째 레이블이 늘어나서 사이즈를 맞춰주게 된다.

img

이번에는 3개의 레이블에 Content Compression-Resistance를 왼쪽부터 250, 750, 1000으로 설정해 주었다.

img

  1. CR250으로 설정한 레이블이 극단적으로 늘어나도, 우선순위가 낮기 때문에 750과 1000의 영역으로 컨텐츠를 밀어낼 수 없다.

img

  1. 하지만, CR750으로 설정한 두번째 레이블이 늘어난다면 우선순위가 낮은 첫번째 레이블은 밀려나서 사라지게 되고 CR750 레이블이 덮어버리게 된다.

img

  1. CR1000 레이블이 늘어난다면 길이에 따라 첫번째, 두번째 레이블이 다 가려지게 된다.

늘어나야 하는 경우 Hugging priority가 낮은 녀석이 늘어나고, 줄어들어야 할 경우 Compression-Resistance priority가 낮은 녀석이 줄어들게 된다.

Reference

Apple - Auto Layout Guide

야곰닷넷-오토레이아웃 정복하기