SwiftUI 提供了强大的列表和导航功能,用于展示和管理大量数据。List 和 NavigationView 是最常用的两个容器视图。

重点:

  • List 的基本用法和自定义
  • ForEach 的数据处理
  • NavigationView 的导航控制
  • ScrollView 的滚动视图
  • 性能优化技巧

List 基础用法 Link to heading

简单列表:

struct SimpleListView: View {
    let items = ["项目1", "项目2", "项目3"]
    
    var body: some View {
        List {
            ForEach(items, id: \.self) { item in
                Text(item)
            }
        }
    }
}

自定义列表项:

struct Item: Identifiable {
    let id = UUID()
    let title: String
    let subtitle: String
}

struct CustomListView: View {
    let items = [
        Item(title: "标题1", subtitle: "描述1"),
        Item(title: "标题2", subtitle: "描述2")
    ]
    
    var body: some View {
        List(items) { item in
            VStack(alignment: .leading) {
                Text(item.title)
                    .font(.headline)
                Text(item.subtitle)
                    .font(.subheadline)
                    .foregroundColor(.gray)
            }
            .padding(.vertical, 4)
        }
    }
}

列表编辑功能 Link to heading

支持删除和移动:

struct EditableListView: View {
    @State private var items = ["项目1", "项目2", "项目3"]
    
    var body: some View {
        List {
            ForEach(items, id: \.self) { item in
                Text(item)
            }
            .onDelete(perform: deleteItems)
            .onMove(perform: moveItems)
        }
        .toolbar {
            EditButton()
        }
    }
    
    func deleteItems(at offsets: IndexSet) {
        items.remove(atOffsets: offsets)
    }
    
    func moveItems(from source: IndexSet, to destination: Int) {
        items.move(fromOffsets: source, toOffset: destination)
    }
}

基础导航:

struct NavigationDemo: View {
    var body: some View {
        NavigationView {
            List {
                NavigationLink("详情页面") {
                    DetailView()
                }
                NavigationLink("设置页面") {
                    SettingsView()
                }
            }
            .navigationTitle("主页")
            .navigationBarTitleDisplayMode(.large)
        }
    }
}

自定义导航栏:

struct CustomNavigationView: View {
    @State private var isShowingSheet = false
    
    var body: some View {
        NavigationView {
            List {
                // 列表内容
            }
            .navigationTitle("主页")
            .toolbar {
                ToolbarItem(placement: .navigationBarLeading) {
                    Button(action: {
                        // 左侧按钮动作
                    }) {
                        Image(systemName: "line.horizontal.3")
                    }
                }
                
                ToolbarItem(placement: .navigationBarTrailing) {
                    Button(action: {
                        isShowingSheet = true
                    }) {
                        Image(systemName: "plus")
                    }
                }
            }
        }
        .sheet(isPresented: $isShowingSheet) {
            AddItemView()
        }
    }
}

ScrollView 的使用 Link to heading

基础滚动视图:

struct ScrollDemo: View {
    var body: some View {
        ScrollView {
            VStack(spacing: 20) {
                ForEach(0..<20) { index in
                    Text("项目 \(index)")
                        .frame(maxWidth: .infinity)
                        .padding()
                        .background(Color.blue.opacity(0.1))
                }
            }
            .padding()
        }
    }
}

水平滚动:

ScrollView(.horizontal, showsIndicators: false) {
    HStack(spacing: 15) {
        ForEach(items) { item in
            ItemCard(item: item)
        }
    }
    .padding(.horizontal)
}

性能优化 Link to heading

  1. 懒加载列表:
struct LazyListView: View {
    var body: some View {
        ScrollView {
            LazyVStack {
                ForEach(0..<1000) { index in
                    Text("Row \(index)")
                        .onAppear {
                            // 当项目出现时加载数据
                        }
                }
            }
        }
    }
}
  1. 列表项重用:
struct OptimizedListView: View {
    let items: [Item]
    
    var body: some View {
        List(items) { item in
            ListRowView(item: item)
                .listRowInsets(EdgeInsets())
                .listRowBackground(Color.clear)
        }
    }
}

struct ListRowView: View {
    let item: Item
    
    var body: some View {
        // 复杂的行视图内容
    }
}

实用技巧 Link to heading

  1. 分组列表:
struct GroupedListView: View {
    var body: some View {
        List {
            Section(header: Text("第一组")) {
                Text("项目 1")
                Text("项目 2")
            }
            
            Section(header: Text("第二组")) {
                Text("项目 3")
                Text("项目 4")
            }
        }
        .listStyle(GroupedListStyle())
    }
}
  1. 下拉刷新:
struct RefreshableListView: View {
    @State private var items: [Item] = []
    
    var body: some View {
        List(items) { item in
            ItemRow(item: item)
        }
        .refreshable {
            // 异步加载数据
            await loadData()
        }
    }
    
    func loadData() async {
        // 刷新数据的异步操作
    }
}

常见问题 Link to heading

  1. 列表选择状态:
struct SelectableListView: View {
    @State private var selection: Set<UUID> = []
    let items: [Item]
    
    var body: some View {
        List(items, selection: $selection) { item in
            Text(item.title)
        }
        .environment(\.editMode, .constant(.active))
    }
}
  1. 导航返回处理:
struct NavigationHandling: View {
    @Environment(\.dismiss) private var dismiss
    
    var body: some View {
        Button("返回") {
            dismiss()
        }
    }
}
  1. 滚动位置控制:
struct ScrollPositionDemo: View {
    @State private var scrollToIndex: Int?
    
    var body: some View {
        ScrollViewReader { proxy in
            List(0..<100, id: \.self) { index in
                Text("Row \(index)")
                    .id(index)
            }
            .onChange(of: scrollToIndex) { index in
                if let index = index {
                    withAnimation {
                        proxy.scrollTo(index, anchor: .center)
                    }
                }
            }
        }
    }
}

列表和导航是 iOS 应用中最常用的界面模式。SwiftUI 通过声明式语法简化了这些功能的实现,同时提供了足够的灵活性来满足各种定制需求。在实际开发中,需要注意性能优化和用户体验的平衡。