SwiftUI列表多选后批量拖动排序问题求助
SwiftUI列表实现多选拖动同步移动
默认的onMove回调只会响应当前拖动行的索引,要实现选中行一起移动,需要手动处理选中项的位置调整逻辑,以下是修改后的完整代码:
import SwiftUI struct ContentView: View { @State var items = ["Test 1", "Test 2", "Test 3", "Test 4", "Test 5", "Test 6"] @State var selectedItems: Set<String> = .init() var body: some View { NavigationView { List(selection: $selectedItems) { ForEach(items, id: \.self) { item in Text(item).tag(item) } .onMove(perform: moveSelectedItems) } #if os(iOS) .navigationBarItems(trailing: EditButton()) #endif } .padding() } private func moveSelectedItems(from source: IndexSet, to destination: Int) { // 无选中项时执行默认移动逻辑 guard !selectedItems.isEmpty else { items.move(fromOffsets: source, toOffset: destination) return } withAnimation { // 获取所有选中项的原始索引 let selectedIndices = items.indices.filter { selectedItems.contains(items[$0]) } // 排除当前拖动的索引,避免重复处理 var indicesToMove = selectedIndices if let draggedIndex = source.first { indicesToMove.remove(draggedIndex) } // 先处理除拖动项外的其他选中项 var adjustedDestination = destination for index in indicesToMove.sorted() { // 根据原始索引位置调整目标偏移量,避免位置计算错误 let offset = index < source.first! ? 1 : 0 items.move(fromOffsets: IndexSet(integer: index), toOffset: adjustedDestination + offset) } // 最后处理拖动的项 items.move(fromOffsets: source, toOffset: adjustedDestination + indicesToMove.count) // 更新选中集合,保证移动后选中状态同步 selectedItems = Set(items[adjustedDestination..<adjustedDestination + selectedItems.count]) } } }
关键逻辑说明
- 自定义
moveSelectedItems方法替代默认移动逻辑,优先判断是否存在选中项 - 提取所有选中项的索引,排除当前拖动的索引以避免重复操作
- 逐个移动其他选中项时,根据原始索引位置动态调整目标偏移量,确保位置计算准确
- 移动完成后更新选中集合,保持选中状态与移动后的列表项同步
内容的提问来源于stack exchange,提问作者Dev_101
相关产品推荐
相关产品推荐

