modifire
는 간격 및 정렬 같은 추가 제어를 제공정적인 뷰 세트를 2차원 레이아웃으로 나타내기
Pet
모델 정의Grid
와 GridRow
로 구성gridColumnAlignment
gridCellColumns
수정자로 단일 뷰가 몇 개의 열에 걸쳐 있는지 알려줌HStack으로 하면 버튼이 text에 맞게 크기가 조정됨
-> 텍스트의 max width를 infinity로 하면 늘어날 수 있음
-> 각 버튼의 크기는 같지만 컨테이너 만큼 커짐 😔
버튼의 이상적인 크기를 요청하고 가장 넓은 것을 찾아 버튼에 제공하는 custom stack이 없나? -> Layout
레이아웃 엔진과 상호 작용할 수 있는 사용자 지정 뷰 컨테이너 타입을 만들 수 있는 프로토콜
텍스트 넓이 만큼을 최대 넓이로 갖도록 하는 사용자 지정 컨테이너 만들기
두 가지 required 메서드 구현
레이아웃 컨테이너의 크기를 계산하고 반환
레이아웃의 하위 뷰가 표시될 위치를 알려줌
Geometry Reader
는 뷰 크기를 측정하기 위한 도구
Container -> Geometry reader -> Subview
-> 정보가 아래로 흐름
순위 별로 이미지 높이를 다르게 회전하자 -> 역시 Layout 프로토콜을 이용하면 가능
replacingUnspecifiedDimensions
순위를 어떻게 받아와서 회전을 계산하지?
레이아웃은 뷰가 아닌 하위 뷰 프록시에만 접근 가능
=> 레이아웃 프로토콜은 하위 뷰에 값을 저장하고 프로토콜 메서드 내부에서 값을 읽을 수 있다!
layourValue
수정자를 통해 값 설정이상적인 크기를 갖도록 하고 너비를 제한하지 않아 디스플레이 너비를 초과하는 문제가 발생할 수 있음 🙁
=> ViewThatFits
뷰 컬렉션에서 사용 가능한 공간에 맞는 뷰를 자동으로 선택하는 컨테이너
ViewThatFits로 래핑하면 버튼을 다르게 배열해야 할 때 SwiftUI가 파악할 수 있음
ViewThatFits {
MyEqualWidthHStack {
Buttons(pets: $pets)
}
MyEqualWidthVStack {
Buttons(pets: $pets)
}
}
여러 컨테이너를 넣어 상황에 맞는 컨테이너를 선택하도록 함
레이아웃 타입 간에 원활한 전환 추가
모두 동점인 경우는 회전 Layout으로 표시 불가 -> 모두 동점일 땐 HStack을 이용하도록 변환
=> AnyLayout
AnyLayout을 사용하면 단일 뷰 계층 구조에 다른 레이아웃을 적용할 수 있음
-> 한 레이아웃에서 다른 레이아웃으로 전환 가능
let layout = isThreeWayTie ? AnyLayout(HStack()) : AnyLayout(MyRadialLayout())
layout {
ForEach(pets) { pet in
Avator(pet: pet)
.rank(rank(pet))
}
}
AnyLayout에 교체할 레이아웃을 넣어 조건에 따라 변경
- Grid: 정적 정보의 고도로 사용자 정의 가능한 2차원 레이아웃
- Layout: 고유한, 재사용 가능한 레이아웃 또는 특정 사례를 레이앗을 정의할 수 있음
- ViewThatFits: 가능한 뷰 공간에서 가장 잘 맞도록
- AnyLayout: 레이아웃 타입 간의 원활하게 전환 가능