Skip to Content
iOS📐 LayoutStacks (VStack, HStack, ZStack)

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ải

2. 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 baseline

3. 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 .bottomTrailing

4. 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

StackHướngAlignment mặc định
VStackDọc.center
HStackNgang.center
ZStackChồng.center

Lazy versions: LazyVStack, LazyHStack cho danh sách dài

Last updated on