Mysteries of Auto Layout, Part 1

Eddy📱·2022년 8월 15일
0

WWDC

목록 보기
1/14
post-thumbnail

WWDC Mysteries of Auto Layout, Part 1

Auto Layout is a powerful constraint-based layout engine that can drive complex and dynamic interfaces on both iOS and OS X.

AutoLayout은 constraint-based 레이아웃 엔진이다.

StackView

StackView는 자식 레이아웃을 알아서 관리하기 때문에 제약을 간소화할 수 있다.
stackView로 axis에 따른 alignment와 distribution을 설정할 수 있다.

alignment

  • horizontal
  • vertical

distribution

demo

  • 목표

복잡한 제약을 가지는 UI를 StackView를 통해서 간단히 표현해보자!

  • 최상위 StackView와 상위 뷰와의 오토 레이아웃만을 설정한다.

  • 문제 상황 1 : Segmented Control이 늘어났다.

  • 이유: 모든 priority가 동일하다.

  • 해결1: segmented control의 content-hugging priority 와 content compresstion priority를 올린다.

  • 문제 상황 2: 레이블과 별점 사이에 새로운 버튼을 추가하라는 요청!

  • 해결2: StackView에 버튼 drop!

animation 적용하기 쉽다.

레이아웃이 망가지지 않고 애니메이션이 적용된다.

스택뷰의 장점은 아래와 같다.

  • 만들기 쉽다
  • 유지하기 쉽다
  • 많은 구성요소를 넣을 수 있다
  • 가볍다(모든 부분 background render할 필요 없고 특별한 transform Layer class가 render 할 필요 없게 해준다. 그래서 이게 스택뷰를 빠르게 동작하도록 해준다)

layout engine

  • 뷰에 제약조건을 추가 삭제하는 것 보다는 activate, deactivate를 하는 것이 더 좋다!

  • 장점
    contraint가 container를 알아서 찾아간다.
    더 효율적이다.
    레이아웃 조절을 위해 모든 뷰를 알 필요가 없다.

  • add, remove 했을 때 문제 예시

예를 들어 아이패드앱인데 두개의 앱을 켜놓고 add, remove로 하도록 했다.

그랬더니 두개의 앱중 하나가 이상하게 나오고 그것을 다시 보이게 했더니 이상하게 나온다.

이처럼 이상하게 나오는 것을 확인할 수 있다. 그러므로 remove로 하게된다면 constarints가 이상하게 바뀐다.

모든 레이아웃을 deactivate(deactivate self.view.constraints)하지 마라! -> 레이아웃이 이상하게 잡힌다.

대신에 조절하려는 참조값을 가져라!

view sizing: intrinsic content size

contents에 맞게 사이즈를 결정한다.

-> 정확한 레이아웃 사이즈를 보장하지는 못한다.
-> 이유: adaptability 때문이다. 이것이 strectch, shirnk 뷰를 하기 때문에 보장할 수 없다.

  • intinsicContentSize를 override해서 사용할 수 있는 3가지 요인들이 있다.
  1. 사이즈 정보가 constraints에서부터 오지 않을 경우에 사용한다.
  2. 만약 뷰가 커스텀으로 drawing될 때 사용한다.
  3. invalidate를 책임져야할 떄 사용해야한다. 왜냐하면 이것이 dynamic size, localization에 따라 사이즈가 동적으로 변하기 떄문이다.

self sizing table view cell

문제:

해결: 레이블 레이아웃 조절: top space to container margin & bottm space to container margin

여전히 문제 존재가 존재한다. 레이블이 충분히 크지 않아서 이미지가 잘린다.

레이블이 최소한 이미지 높이는 되어야 한다는 조건이 필요하다!

이미지와 레이블 높이를 맞춘다.

관계식이 ">="이 되도록 변경

해결:

ambiguity: priority

ambiguity는 언제 발생할까??

  • 레이아웃 조건이 부족할 때
  • equal-nonrequired priority
    => layout engine이 임의로 레이아웃을 선택

레이아웃 수치가 같으면 모호함!

=> view content 우선도를 required 하지마라
ex. localization에 대응 못함

기본적으로 세팅하는 것을 요구하지 않는다. 그러나 이는 만족스럽지 못한 constraints를 보여줄 수 있다.

문제: 기본 content hugging 우선도가 250으로 동일 -> 레이아웃 엔진은 뭘 선택할지 몰라서 발생하는 문제

해결: 버튼의 content hugging을 낮춘다.

문제: 기본 compression resistance가 750으로 동일

해결: 모든 text가 보인다!

text alignmnet

  1. baseline

first baseline: 첫 줄의 글자 아래 부분

=> 텍스트 줄이 늘어도 버튼의 위치는 동일

last baseline: 마지막 줄의 글자 아래 부분

  1. leading & trailing > right & left
    => localization(글 작성 방향에 따라)

아랍어 같은 부분에서 오른쪽에서 왼쪾으로 읽으므로 지역화에 대응되어있지 않다

leading, trailing으로 해주면 다른 나라에 맞게 설정해줄 수 있다

  1. Alignment Rect

보통은 Frame과 동일하다.

=> alignmnetRectInset override 해라

💡 frame, alignment rectangle은 일반적으로 다르지 않지만, 뱃지/그림자와 같은 효과가 추가된다면 달라진다.
Auto Layout은 alignment rectangle을 사용한다.
만약 위와 같은 체크박스를 frame 기준으로 view의 center로 맞춘다면 우리가 원하는 중앙에 배치되지 않고 약간 왼쪽으로 쏠리게 될 것이다.
따라서 alignment rectangle을 기준으로 Auto Layout을 적용한다.

참고자료

alignment reactangle 확인하는법

xcode menu -> Debug menu -> show Alignment Rect
or AlignmnetRectForFrame로 디버깅 모드에서 확인할 수 있다.

레이아웃 엔진 빌드

아래와 같이 레이아웃 엔진이 어떤 것이 포함되는지 볼 수 있다.

이러면 이제 원하는 레이아웃이 만들어지는 프로세스를 이해할 수 있다.

요약

profile
Make a better world

0개의 댓글