Padding và Frame trong SwiftUI
1. Padding
Cơ bản
Text("Hello")
.padding() // Padding đều 4 hướng
Text("Hello")
.padding(20) // 20 points đều
Text("Hello")
.padding(.horizontal) // Trái phải
.padding(.vertical, 10) // Trên dưới 10Các hướng
.padding(.all) // Tất cả
.padding(.horizontal) // Trái + phải
.padding(.vertical) // Trên + dưới
.padding(.top) // Chỉ trên
.padding(.bottom) // Chỉ dưới
.padding(.leading) // Chỉ trái
.padding(.trailing) // Chỉ phảiMultiple Edges
Text("Hello")
.padding([.top, .leading], 20)
Text("Hello")
.padding(.horizontal, 16)
.padding(.vertical, 8)EdgeInsets
Text("Hello")
.padding(EdgeInsets(
top: 10,
leading: 20,
bottom: 10,
trailing: 20
))2. Frame
Fixed Size
Text("Hello")
.frame(width: 200, height: 100)
Rectangle()
.frame(width: 100, height: 100)Min/Max Size
Text("Hello")
.frame(minWidth: 100, maxWidth: 300)
Text("Hello")
.frame(maxWidth: .infinity) // Full width
Text("Hello")
.frame(maxWidth: .infinity, maxHeight: .infinity) // Full screenAlignment trong Frame
Text("Hello")
.frame(width: 200, height: 100, alignment: .topLeading)
Text("Hello")
.frame(maxWidth: .infinity, alignment: .leading)3. Padding + Background
Thứ tự quan trọng!
// Background bao padding
Text("Hello")
.padding()
.background(.blue)
// Background chỉ text, padding bên ngoài
Text("Hello")
.background(.blue)
.padding()4. Common Patterns
Button
Button("Submit") { }
.padding(.horizontal, 24)
.padding(.vertical, 12)
.background(.blue)
.foregroundColor(.white)
.cornerRadius(8)Card
VStack(alignment: .leading, spacing: 8) {
Text("Title")
.font(.headline)
Text("Description")
.font(.subheadline)
.foregroundColor(.gray)
}
.padding()
.frame(maxWidth: .infinity, alignment: .leading)
.background(.white)
.cornerRadius(12)
.shadow(radius: 2)Full Width Container
VStack {
Text("Content")
}
.frame(maxWidth: .infinity)
.padding()
.background(.gray.opacity(0.1))Centered Content
Text("Centered")
.frame(maxWidth: .infinity, maxHeight: .infinity)
.background(.blue.opacity(0.1))5. fixedSize
Ngăn text bị truncate.
// Có thể bị cắt
Text("Very long text here that might get truncated")
.frame(width: 100)
// Không bị cắt
Text("Very long text here that won't get truncated")
.fixedSize()
.frame(width: 100)
// Chỉ fix một chiều
Text("Long text")
.fixedSize(horizontal: true, vertical: false)6. layoutPriority
Ưu tiên space allocation.
HStack {
Text("Short")
Text("This is a very long text that needs more space")
.layoutPriority(1) // Được ưu tiên
Text("Short")
}7. GeometryReader
Đọc size của container.
GeometryReader { geometry in
VStack {
Text("Width: \(Int(geometry.size.width))")
Text("Height: \(Int(geometry.size.height))")
Rectangle()
.fill(.blue)
.frame(
width: geometry.size.width * 0.5,
height: geometry.size.height * 0.3
)
}
}Responsive Design
GeometryReader { geo in
let isCompact = geo.size.width < 500
if isCompact {
VStack { content }
} else {
HStack { content }
}
}8. Practical Examples
Login Form
VStack(spacing: 16) {
TextField("Email", text: $email)
.padding()
.background(.gray.opacity(0.1))
.cornerRadius(8)
SecureField("Password", text: $password)
.padding()
.background(.gray.opacity(0.1))
.cornerRadius(8)
Button("Login") { }
.frame(maxWidth: .infinity)
.padding()
.background(.blue)
.foregroundColor(.white)
.cornerRadius(8)
}
.padding(.horizontal, 24)Header với Padding
VStack(spacing: 0) {
HStack {
Text("Home")
.font(.largeTitle.bold())
Spacer()
Image(systemName: "bell")
.font(.title2)
}
.padding()
.background(.white)
Divider()
// Content
ScrollView {
// ...
}
}📝 Tóm tắt
| Modifier | Mục đích |
|---|---|
.padding() | Thêm khoảng cách bên trong |
.frame() | Đặt kích thước |
.fixedSize() | Ngăn truncation |
.layoutPriority() | Ưu tiên space |
Tips:
- Thứ tự modifiers quan trọng!
.frame(maxWidth: .infinity)cho full width- Dùng
GeometryReadercho responsive layout
Last updated on