Skip to Content
iOS📋 Lists và CollectionsLazyVStack và LazyHStack

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

VStackLazyVStack
Render all at onceRender on-demand
Small listsLarge lists
Không cần ScrollViewCầ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 ScrollView
  • LazyHStack - Lazy horizontal
  • pinnedViews - Sticky headers/footers
  • Dùng cho danh sách dài để tối ưu performance
Last updated on