SwiftUI迁移至NavigationStack遇两问题:List Toolbar位置及NavigationLink失效
问题1:List编辑时Toolbar需显示在List上方而非屏幕顶部
原因
原嵌套NavigationView方案中,List内部的导航栏独立于根导航栏,编辑工具栏自然附着在List上方。但NavigationStack采用统一导航层级,默认工具栏会显示在屏幕顶部的根导航栏区域,无法直接复用原嵌套方式。
解决方案
通过监听EditMode状态,在List内部添加自定义工具栏,仅在编辑激活时显示在List顶部,既满足需求又避免嵌套NavigationStack的问题。
示例代码:
struct FirstTabView: View { @State private var items = ["Item 1", "Item 2", "Item 3"] @Environment(\.editMode) private var editMode var body: some View { List { // 编辑模式下显示自定义工具栏在List顶部 if editMode?.wrappedValue == .active { HStack { Button("删除选中项") { // 实现删除逻辑,例如移除selectedItems中的元素 } Spacer() Button("排序") { // 实现排序/移动逻辑 } } .padding(.horizontal) .frame(height: 44) .background(Color(.systemGray6)) } ForEach(items, id: \.self) { item in NavigationLink(item, destination: DetailView(item: item)) } } .toolbar { EditButton() // 根导航栏的编辑按钮 } .navigationTitle("首页") } } struct DetailView: View { let item: String var body: some View { Text(item) .navigationTitle(item) } }
问题2:List添加selection后,非编辑模式下NavigationLink点击无响应
原因
当List绑定selection属性后,非编辑模式下点击列表行的默认行为会被selection的选中逻辑覆盖,导致NavigationLink无法触发跳转。
解决方案
根据EditMode状态动态设置selection绑定:仅在编辑模式下启用selection,非编辑模式下将selection设为nil,让NavigationLink恢复点击跳转功能。
示例代码:
struct FirstTabView: View { @State private var items = ["Item 1", "Item 2", "Item 3"] @State private var selectedItems = Set<String>() @Environment(\.editMode) private var editMode var body: some View { // 动态绑定selection:仅编辑模式下生效 List(items, id: \.self, selection: editMode?.wrappedValue == .active ? $selectedItems : nil) { item in NavigationLink(item, destination: DetailView(item: item)) } .toolbar { EditButton() // 编辑模式下显示批量操作按钮 if editMode?.wrappedValue == .active { Button("删除") { items.removeAll { selectedItems.contains($0) } selectedItems.removeAll() } } } .navigationTitle("首页") } }
内容的提问来源于stack exchange,提问作者Serhii R
相关产品推荐
相关产品推荐

