흔히 사용하는 HStack, VStack, ZStack은 단순 View이다.
HStack : 요소들을 수평으로 배치
VStack : 요소들을 수직으로 배치
ZStack : 요소들을 겹치게 배치
디자인된 화면을 코드로 옮기기 전에, 다양한 유형의 stack view를 어떻게 사용하여 레이아웃을 구성할지에 대해 먼저 고민해봐야 한다.
복잡하게 구성된 화면을 잘게 쪼개어 볼 줄 알아야 한다.
struct ProfileView: View {
var body: some View {
ZStack(alignment: .bottom) {
Image("ProfilePicture")
.resizable
.aspectRatio(contentMode: .fit)
HStack {
VStack(alignment: .leading) {
Text("Rachel Chiseck")
.font(.headline)
Text("Chief Executive Officer")
.font(.subheadline)
}
Spacer()
}
.padding()
.foregroundColor(.primary)
.background(Color.primary
.colorInvert()
.opacity(0.75))
}
}
}
Stack 내에 포함된 view들을 정렬하려면,
를 조합하여 사용하면 된다.
명시적인 Height와 Width로 View 프레임 지정 ❌
구조 및 계층을 정의하고 가용 공간을 채울 수 있도록 View 확장 ✅
명시적인 레이아웃 조정 방법에는
와 같은 방법이 있지만, adaptive & flexible하게 레이아웃을 구성할 수 없을 때만 사용하자.
❗️ view layout 미세 조정하는 방법은 Making Fine Adjustments to a View's Position 참고.
Depth 추가하는 방법은 앞에서 ZStack을 사용하면 된다고 했는데, 이 외에도 경우에 따라 다른 방법을 사용할 수 있다.
view 위에 view를 배치하는 modifier
수정 중인 view 뒤에 다른 view를 배치하는 modifier
최종 레이아웃의 크기를 어떻게 결정할 것인지에 따라서,
stack-based(ZStack 사용)
모든 요소가 포함된 view의 최종 사이즈를 가져올 때 사용
view modifier(overlay, background 사용)
레이아웃 크기를 담당하는 지배적인 view가 있을 경우 사용
두 접근 방식 중 하나를 선택하여 사용하면 된다.
struct ProfileViewWithOverlay: View {
var body: some View {
VStack {
Image("ProfilePicture")
.resizable()
.aspectRatio(contentMode: .fit)
.overlay(ProfileDetail(), alignment: .bottom)
}
}
}
struct ProfileDetail: View {
var body: some View {
HStack {
VStack(alignment: .leading) {
Text("Rachael Chiseck")
.font(.headline)
Text("Chief Executive Officer")
.font(.subheadline)
}
Spacer()
}
.padding()
.foregroundColor(.primary)
.background(Color.primary
.colorInvert()
.opacity(0.75))
}
}
요소 사이에는 기본적으로 들어가는 spacing이 있다.
HStack은 수평으로, VStack은 수직으로
HStack {
Text("First")
Text("Second")
}
VStack {
Text("First")
Text("Second")
}
spacing 계산을 쉽게 하려면, 아래처럼 (spacing: 0)으로 한 다음, .padding()을 넣어주면 된다.
VStack(spacing: 0) { Text("First") .padding(.bottom, 16) Text("Second") }