LazyVStack và LazyHStack
1. LazyVStack
Chỉ render items visible trên màn hình.
ScrollView {
LazyVStack {
ForEach(0..<10000) { index in
Text("Row \(index)")
.onAppear {
print("Row \(index) appeared")
}
}
}
}2. LazyHStack
ScrollView(.horizontal) {
LazyHStack {
ForEach(items) { item in
ItemCard(item: item)
}
}
}3. Pinned Headers
ScrollView {
LazyVStack(pinnedViews: [.sectionHeaders]) {
Section {
ForEach(0..<20) { _ in
Text("Item")
}
} header: {
Text("Section 1")
.frame(maxWidth: .infinity)
.background(.white)
}
Section {
ForEach(0..<20) { _ in
Text("Item")
}
} header: {
Text("Section 2")
.frame(maxWidth: .infinity)
.background(.white)
}
}
}4. VStack vs LazyVStack
| VStack | LazyVStack |
|---|---|
| Render all at once | Render on-demand |
| Small lists | Large lists |
| Không cần ScrollView | Cần ScrollView |
// ❌ Bad for large lists
VStack {
ForEach(0..<10000) { Text("\($0)") }
}
// ✅ Good for large lists
ScrollView {
LazyVStack {
ForEach(0..<10000) { Text("\($0)") }
}
}5. Infinite Scroll
struct InfiniteScrollView: View {
@State private var items = Array(0..<20)
@State private var isLoading = false
var body: some View {
ScrollView {
LazyVStack {
ForEach(items, id: \.self) { item in
Text("Item \(item)")
.onAppear {
if item == items.last {
loadMore()
}
}
}
if isLoading {
ProgressView()
}
}
}
}
func loadMore() {
guard !isLoading else { return }
isLoading = true
DispatchQueue.main.asyncAfter(deadline: .now() + 1) {
let newItems = items.count..<(items.count + 20)
items.append(contentsOf: newItems)
isLoading = false
}
}
}📝 Tóm tắt
LazyVStack- Lazy vertical, cần ScrollViewLazyHStack- Lazy horizontalpinnedViews- Sticky headers/footers- Dùng cho danh sách dài để tối ưu performance
Last updated on