Stacks trong SwiftUI
1. VStack (Vertical Stack)
Sắp xếp views theo chiều dọc.
VStack {
Text("First")
Text("Second")
Text("Third")
}
// Với spacing và alignment
VStack(alignment: .leading, spacing: 20) {
Text("Left aligned")
Text("Items")
Text("Here")
}Alignment options
VStack(alignment: .leading) { } // Căn trái
VStack(alignment: .center) { } // Căn giữa (mặc định)
VStack(alignment: .trailing) { } // Căn phải2. HStack (Horizontal Stack)
Sắp xếp views theo chiều ngang.
HStack {
Text("Left")
Text("Center")
Text("Right")
}
// Với spacing và alignment
HStack(alignment: .top, spacing: 16) {
Image(systemName: "person")
VStack(alignment: .leading) {
Text("Name")
Text("Subtitle").font(.caption)
}
}Alignment options
HStack(alignment: .top) { } // Căn trên
HStack(alignment: .center) { } // Căn giữa (mặc định)
HStack(alignment: .bottom) { } // Căn dưới
HStack(alignment: .firstTextBaseline) { } // Theo baseline3. ZStack (Z-axis Stack)
Xếp chồng views lên nhau.
ZStack {
Color.blue // Background (dưới cùng)
Text("On Top") // Foreground (trên cùng)
}
// Với alignment
ZStack(alignment: .bottomTrailing) {
Image("photo")
Text("Badge")
.padding(4)
.background(.red)
.foregroundColor(.white)
}Alignment options
.topLeading .top .topTrailing
.leading .center .trailing
.bottomLeading .bottom .bottomTrailing4. Nested Stacks
VStack {
// Header
HStack {
Image(systemName: "person.circle")
.font(.largeTitle)
VStack(alignment: .leading) {
Text("John Doe")
.font(.headline)
Text("iOS Developer")
.font(.subheadline)
.foregroundColor(.gray)
}
Spacer()
}
// Content
Text("Profile content here...")
.padding(.top)
}
.padding()5. Card Layout
struct CardView: View {
var body: some View {
VStack(alignment: .leading, spacing: 12) {
// Image
ZStack(alignment: .topTrailing) {
Image("photo")
.resizable()
.aspectRatio(contentMode: .fill)
.frame(height: 200)
.clipped()
// Badge
Text("NEW")
.font(.caption.bold())
.padding(.horizontal, 8)
.padding(.vertical, 4)
.background(.red)
.foregroundColor(.white)
.cornerRadius(4)
.padding(8)
}
// Content
VStack(alignment: .leading, spacing: 4) {
Text("Card Title")
.font(.headline)
Text("Card description goes here")
.font(.subheadline)
.foregroundColor(.gray)
}
.padding(.horizontal)
.padding(.bottom)
}
.background(.white)
.cornerRadius(16)
.shadow(radius: 4)
}
}6. LazyVStack và LazyHStack
Dùng cho danh sách dài - chỉ render items visible.
ScrollView {
LazyVStack(spacing: 12) {
ForEach(0..<1000) { index in
Text("Item \(index)")
.padding()
.frame(maxWidth: .infinity)
.background(.gray.opacity(0.1))
}
}
.padding()
}
ScrollView(.horizontal) {
LazyHStack(spacing: 12) {
ForEach(0..<100) { index in
RoundedRectangle(cornerRadius: 8)
.fill(.blue)
.frame(width: 100, height: 100)
.overlay(Text("\(index)").foregroundColor(.white))
}
}
.padding()
}7. Practical Examples
Profile Header
HStack(spacing: 16) {
Image(systemName: "person.circle.fill")
.resizable()
.frame(width: 60, height: 60)
.foregroundColor(.blue)
VStack(alignment: .leading, spacing: 4) {
Text("John Doe")
.font(.title2.bold())
Text("@johndoe")
.font(.subheadline)
.foregroundColor(.gray)
}
Spacer()
Button("Follow") { }
.buttonStyle(.borderedProminent)
}
.padding()Feature Row
HStack {
ZStack {
Circle()
.fill(.blue.opacity(0.1))
.frame(width: 44, height: 44)
Image(systemName: "star.fill")
.foregroundColor(.blue)
}
VStack(alignment: .leading) {
Text("Premium")
.font(.headline)
Text("Unlock all features")
.font(.caption)
.foregroundColor(.gray)
}
Spacer()
Image(systemName: "chevron.right")
.foregroundColor(.gray)
}
.padding()📝 Tóm tắt
| Stack | Hướng | Alignment mặc định |
|---|---|---|
VStack | Dọc | .center |
HStack | Ngang | .center |
ZStack | Chồng | .center |
Lazy versions: LazyVStack, LazyHStack cho danh sách dài
Last updated on