LazyVStack và LazyHStack
1. LazyVStack
Phần tiêu đề “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
Phần tiêu đề “2. LazyHStack”ScrollView(.horizontal) { LazyHStack { ForEach(items) { item in ItemCard(item: item) } }}3. Pinned Headers
Phần tiêu đề “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
Phần tiêu đề “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 listsVStack { ForEach(0..<10000) { Text("\($0)") }}
// ✅ Good for large listsScrollView { LazyVStack { ForEach(0..<10000) { Text("\($0)") } }}5. Infinite Scroll
Phần tiêu đề “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
Phần tiêu đề “📝 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