如何让新增至Chosen列表的项立即支持拖拽与删除?
问题
我有一个包含两个分区的列表:
- chosen选项区:支持重排与删除操作
- suggested选项区:可将区内项添加至chosen区
目前遇到的问题是:从suggested区新增到chosen的项(比如"five""six")无法立即支持拖拽与删除编辑。另外我发现,如果把suggested分区里的ForEach(filteredSuggestions(), id: \.self)换成ForEach(suggested, id: \.self),chosen分区的显示会符合预期,但suggested分区的内容就不对了。
相关代码如下:
struct EditorView: View { @State var chosen = ["one", "two", "three", "four"] let suggested = ["five", "six", "seven", "eight"] var body: some View { List { Section { ForEach(chosen, id: \.self) { item in Text(item) } .onDelete{ _ in } .onMove{ _, _ in } } header: { Text("chosen") } Section { ForEach(filteredSuggestions(), id: \.self) { item in HStack(spacing: 14) { Button { chosen.append(item) } label: { Image(systemName: "plus.circle.fill") .imageScale(.large) .foregroundStyle(.green) } Text(item) } } } header: { Text("suggested") } } .environment(\.editMode, .constant(.active)) } private func filteredSuggestions() -> [String] { return suggested.filter { item in !chosen.contains(item) } } }
解决方法
问题根源在于ForEach的数据源处理和SwiftUI的视图更新逻辑:用方法返回过滤后的数组时,每次chosen变化都会生成新数组实例,导致SwiftUI刷新视图时,chosen分区的新增项没有正确关联编辑状态。可以通过以下步骤修复:
将过滤方法改为计算属性
把filteredSuggestions()改成计算属性,让SwiftUI更高效地追踪数据源变化,避免频繁生成新数组实例:private var filteredSuggestions: [String] { suggested.filter { !chosen.contains($0) } }完善编辑逻辑并添加状态更新动画
原来的onDelete和onMove是空实现,需要补充实际逻辑;同时给添加操作加上动画,确保SwiftUI正确更新chosen分区的视图状态,让新增项立即获得编辑能力。
完整修复后的代码:
struct EditorView: View { @State var chosen = ["one", "two", "three", "four"] let suggested = ["five", "six", "seven", "eight"] private var filteredSuggestions: [String] { suggested.filter { !chosen.contains($0) } } var body: some View { List { Section { ForEach(chosen, id: \.self) { item in Text(item) } .onDelete(perform: deleteItem) .onMove(perform: moveItem) } header: { Text("chosen") } Section { ForEach(filteredSuggestions, id: \.self) { item in HStack(spacing: 14) { Button { withAnimation { chosen.append(item) } } label: { Image(systemName: "plus.circle.fill") .imageScale(.large) .foregroundStyle(.green) } Text(item) } } } header: { Text("suggested") } } .environment(\.editMode, .constant(.active)) } private func deleteItem(at offsets: IndexSet) { chosen.remove(atOffsets: offsets) } private func moveItem(from source: IndexSet, to destination: Int) { chosen.move(fromOffsets: source, toOffset: destination) } }
修复说明
- 计算属性
filteredSuggestions让SwiftUI能精准追踪数据源变化,避免不必要的视图刷新 withAnimation确保添加项时视图平滑过渡,同时让SwiftUI正确识别chosen数组的更新,为新增项绑定编辑状态- 实现
deleteItem和moveItem方法,让删除、重排功能真正可用
内容的提问来源于stack exchange,提问作者routern
相关产品推荐
相关产品推荐

