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))
}
八、注意事项
- 平台差异 :
- iOS:默认带分隔线和点击高亮。
- macOS:支持多列列表和更复杂的交互。
- 性能问题 :
- 避免在列表项视图中包含复杂计算。
- 超长列表优先使用
LazyVStack
。
- 唯一性 :
- 动态数据必须保证
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 的声明式语法,快速构建跨平台的列表界面。