WWDC Mysteries of Auto Layout, Part 1
😎 AutoLayout이란?
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를 사용하면
1) StackView는 자식 레이아웃을 알아서 관리하기 때문에 제약을 간소화할 수 있다.
2) StackView로 axis에 따른 alignment와 distribution을 설정할 수 있다.
horizontal | vertical |
---|---|
demo 예시를 통해 StackView의 장점을 말하고자 하는 파트
이유: 모든 priority가 동일하다.
➡️ 해결: segmented control의 content-hugging priority 와 content compresstion priority를 올린다.
두번째 문제 상황: 레이블과 별점 사이에 새로운 버튼을 추가하라는 요청이 있다.
➡️ 해결: StackView에 버튼 drop!(addArrangedSubview)
⭐️ animation 적용 쉽다!
⭐️ StackView의 장점 요약
📢 다양한 iPhone의 화면 크기가 있다. 이러한 모든 환경에서 작동하도록 layout을 만들고, 단일 화면에 대해 반복하는 시간을 줄여햐한다.
그래서 대부분의 사람들은 아래 그림처럼 몇가지 view와 몇가지 제약을 만들어 일종의 블랙홀에 던진다.
블랙홀안에선 무언가 일어난다. 그리고 우리의 layout이 튀어나온다.
📢 지금부터 "블랙홀(???박스)" 미스테리의 일부를 해결하고 매번 원하는 layout에 도달하도록 하고자 한다.
그 시작은 changing constraints!
이전에는 view의 constraints를 추가/삭제(add/remove)하는 개념이 있었다.
‼️ 더이상 이 개념을 사용하지 말아라!
뷰에 제약조건을 추가/삭제(add/remove)하는 것 보다는 activate, deactivate를 하는 것이 더 좋다!
activate, deactivate의 장점
Things to keep in mind
여기 행성을 보여주는 iPad app이 있다. 이것은 멀티스크린이 가능하다.
옆에 다른 app을 켜고 왼쪽 스크린 크기를 키웠다가 줄였더니, 행성의 배열이 바뀌었다.
이를 해결하기 위해 constraints를 remove로 하도록 했다.
그랬더니 두개의 앱중 하나가 이상하게 나오고 그것을 다시 보이게 했더니 이상하게 나온다.
(여기서 sharedConstraints 라는 개념이 나오는데 뭔지 모르겠음 😅)
이처럼 이상하게 나오는 것을 확인할 수 있다.
그러므로 remove로 하게된다면 constarints가 이상하게 바뀐다.
따라서 특성 컬렉션이 변경되면 변경해야 할 수 있는 다른 제약 조건 집합이 활성화되어 있는지 각 환경에서 확인하고 확인한다.
여기에 행성과의 수직 정렬을 구별하는 8개의 제약 조건이 있는 두 개의 배열이 있다.
따라서 활성화되어 있는지 확인하고 제거하거나 더 이상 원하지 않는 것을 비활성화하고 새 것을 활성화하면 된다.
💡 솔직히 오래전 코드라 이해하기 어렵다. 그냥 하지마라‼️
모든 레이아웃을 deactivate(deactivate self.view.constraints
)하지 마라!
➡️ 레이아웃이 이상하게 잡힌다.
contents에 맞게 사이즈를 결정한다.
정확한 레이아웃 사이즈를 보장하지는 못한다.
➡️ 이유: adaptability 떄문이다. 이것이 strectch, shirnk 뷰를 하기 때문에 보장할 수 없다.
intinsicContentSize를 override해서 사용할 수 있는 3가지 요인들이 있다.
1️⃣ 문제:
🔨 해결:
레이블 레이아웃 조절: top space to container margin & bottm space to container margin
2️⃣ 문제:
➡️ 여전히 문제 존재: 레이블이 충분히 크지 않아서 이미지가 잘림🔨 해결:
레이블이 최소한 이미지 높이는 되어야 한다는 조건이 필요하다!
이미지와 레이블 높이를 맞춘다.
관계식이 ">="이 되도록 변경
최종 해결:
기본적으로 세팅하는 것을 요구하지 않는다. 그러나 이는 만족스럽지 못한 constraints를 보여줄 수 있다.
1️⃣ 문제: 기본 content hugging 우선도가 250으로 동일 -> 레이아웃 엔진은 뭘 선택할지 몰라서 발생하는 문제
localization(글 작성 방향에 따라)
아랍어 같은 부분에서 오른쪽에서 왼쪾으로 읽으므로 지역화에 대응되어있지 않다.
leading, trailing으로 해주면 다른 나라에 맞게 설정해줄 수 있다.
보통은 Frame과 동일
➡️ alignmnetRectInset 오버라이딩 해라
💡frame, alignment rectangle은 일반적으로 다르지 않지만, 뱃지/그림자와 같은 효과가 추가된다면 달라진다.
Auto Layout은 alignment rectangle을 사용한다.
만약 위와 같은 체크박스를 frame 기준으로 view의 center로 맞춘다면 우리가 원하는 중앙에 배치되지 않고 약간 왼쪽으로 쏠리게 될 것이다.
따라서 alignment rectangle을 기준으로 Auto Layout을 적용한다.
xcode menu -> Debug menu -> show Alignment Rect
or AlignmnetRectForFrame로 디버깅 모드에서 확인
아래와 같이 레이아웃 엔진이 어떤 것이 포함되는지 볼 수 있다.
이러면 이제 원하는 레이아웃이 만들어지는 프로세스를 이해할 수 있다.