SwiftUI 8.List介绍和使用

SwiftUI 的 List 组件用于展示可滚动的内容集合,支持静态或动态数据、交互操作(如点击、滑动删除)、分组、自定义样式等。以下是其详细介绍及使用方法:


一、基本用法

1. 静态列表

直接声明固定内容:

swift 复制代码
struct ContentView: View {
    var body: some View {
        List {
            Text("第一项")
            Text("第二项")
            Text("第三项")
        }
    }
}
2. 动态列表

结合 ForEach 动态生成列表项:

swift 复制代码
struct ContentView: View {
    let items = ["苹果", "香蕉", "橙子"]
    
    var body: some View {
        List(items, id: \.self) { item in
            Text(item)
        }
    }
}
  • 要求数据元素唯一(通过 id: \.self 或遵循 Identifiable 协议)。

二、混合内容

静态和动态内容组合:

swift 复制代码
List {
    Text("标题").font(.headline)
    
    ForEach(items, id: \.self) { item in
        Text(item)
    }
    
    Section(header: Text("底部")) {
        Text("其他选项")
    }
}

三、分组与 Section

使用 Section 对列表内容分组:

swift 复制代码
List {
    Section(header: Text("水果"), footer: Text("选择你喜欢的")) {
        ForEach(fruits, id: \.self) { item in
            Text(item)
        }
    }
    
    Section(header: Text("蔬菜")) {
        ForEach(vegetables, id: \.self) { item in
            Text(item)
        }
    }
}
.listStyle(.grouped) // 设置分组样式

四、交互与样式定制

1. 点击事件

通过 .onTapGesture 或结合 NavigationLink

swift 复制代码
List(items, id: \.self) { item in
    Text(item)
        .onTapGesture {
            print("点击了 \(item)")
        }
}

// 或导航跳转
List(items, id: \.self) { item in
    NavigationLink {
        DetailView(item: item)
    } label: {
        Text(item)
    }
}
2. 滑动操作(iOS)

添加滑动删除或自定义操作:

swift 复制代码
List {
    ForEach(items, id: \.self) { item in
        Text(item)
    }
    .onDelete { indexSet in
        // 处理删除逻辑
    }
    .onMove { indices, newOffset in
        // 处理移动逻辑
    }
}
.toolbar {
    EditButton() // 启用编辑模式
}
3. 自定义样式
  • 隐藏分隔线(iOS 15+):

    swift 复制代码
    .listRowSeparator(.hidden)
  • 修改背景颜色

    swift 复制代码
    .listRowBackground(Color.yellow)
  • 禁用选中高亮

    swift 复制代码
    .listStyle(.plain)

五、动态数据绑定

结合 @State@ObservedObject 实现数据动态更新:

swift 复制代码
struct ContentView: View {
    @State private var items = ["苹果", "香蕉", "橙子"]
    
    var body: some View {
        List {
            ForEach(items, id: \.self) { item in
                Text(item)
            }
            .onDelete(perform: deleteItem)
        }
    }
    
    func deleteItem(at offsets: IndexSet) {
        items.remove(atOffsets: offsets)
    }
}

六、性能优化

1. 懒加载

默认情况下,List 是懒加载的,仅渲染可见项。

2. 使用 Identifiable 协议

确保动态数据遵循 Identifiable,避免重复计算 id

swift 复制代码
struct Fruit: Identifiable {
    let id = UUID()
    var name: String
}

List(fruits) { fruit in
    Text(fruit.name)
}
3. 替代方案:LazyVStack

超长列表需谨慎使用 List(某些场景性能不如 LazyVStack):

swift 复制代码
ScrollView {
    LazyVStack {
        ForEach(items) { item in
            Text(item.name)
        }
    }
}

七、高级功能

1. 下拉刷新(iOS 15+)

添加下拉刷新操作:

swift 复制代码
List(items) { item in
    Text(item.name)
}
.refreshable {
    await loadData() // 异步加载数据
}
2. 多选模式(iOS 16+)

启用多选并获取选中项:

swift 复制代码
struct ContentView: View {
    @State private var selections = Set<UUID>()
    let items = [Fruit(name: "苹果"), Fruit(name: "香蕉")]
    
    var body: some View {
        List(items, selection: $selections) { item in
            Text(item.name)
        }
        .toolbar {
            EditButton()
        }
    }
}
3. 自定义列表项视图

完全自定义列表项布局:

swift 复制代码
List(items) { item in
    HStack {
        Image(systemName: "leaf")
        Text(item.name)
        Spacer()
        Button("详情") { /* 操作 */ }
    }
    .padding()
    .background(Color.gray.opacity(0.1))
}

八、注意事项

  1. 平台差异
    • iOS:默认带分隔线和点击高亮。
    • macOS:支持多列列表和更复杂的交互。
  2. 性能问题
    • 避免在列表项视图中包含复杂计算。
    • 超长列表优先使用 LazyVStack
  3. 唯一性
    • 动态数据必须保证 id 唯一,否则可能导致渲染错误。

完整示例

swift 复制代码
struct Fruit: Identifiable {
    let id = UUID()
    var name: String
}

struct ContentView: View {
    @State private var fruits = [
        Fruit(name: "苹果"),
        Fruit(name: "香蕉"),
        Fruit(name: "橙子")
    ]
    
    var body: some View {
        NavigationStack {
            List {
                Section(header: Text("水果列表")) {
                    ForEach(fruits) { fruit in
                        NavigationLink {
                            Text("详情:\(fruit.name)")
                        } label: {
                            HStack {
                                Image(systemName: "leaf")
                                Text(fruit.name)
                            }
                        }
                    }
                    .onDelete(perform: delete)
                }
            }
            .navigationTitle("水果")
            .toolbar {
                EditButton()
            }
            .refreshable {
                await loadMoreData()
            }
        }
    }
    
    func delete(at offsets: IndexSet) {
        fruits.remove(atOffsets: offsets)
    }
    
    func loadMoreData() async {
        // 模拟异步加载
        try? await Task.sleep(nanoseconds: 1_000_000_000)
        fruits.append(Fruit(name: "新水果"))
    }
}

通过 List 组件,你可以高效实现复杂的数据展示与交互逻辑,同时结合 SwiftUI 的声明式语法,快速构建跨平台的列表界面。

相关推荐
努力成为包租婆10 小时前
iOS18 MSSBrowse闪退
ios·objective-c
画个大饼13 小时前
Swift:什么是Optional?其背后的机制是什么?什么是Unconditional Unwrapping?
开发语言·ios·swift
鸿蒙布道师17 小时前
鸿蒙NEXT开发正则工具类RegexUtil(ArkTs)
android·ios·华为·harmonyos·arkts·鸿蒙系统·huawei
只可远观18 小时前
Flutter Dart 集合类型List Set Map详解军 以及循环语句 forEaclh map where any every
windows·flutter·list
二流小码农19 小时前
鸿蒙开发:如何更新对象数组
android·ios·harmonyos
GeniuswongAir20 小时前
苹果新规生效:即日起不再接受iOS 17 SDK编译的应用提交
ios
Ronin3051 天前
【C++】13.list的模拟实现
开发语言·数据结构·c++·list
东坡肘子1 天前
Chrome 会成为 OpenAI 的下一个目标?| 肘子的 Swift 周报 #081
人工智能·swiftui·swift