SwiftUI中拖动调整Item顺序后如何保存位置?
修复SwiftUI List拖动排序后回到原位的问题
你的问题核心是未开启编辑模式,SwiftUI的List默认仅在编辑模式下,.onMove的拖动排序才会真正触发状态更新,否则拖动只是视觉反馈,不会保存新顺序。
以下是两种可行的修复方案:
方案一:添加编辑按钮(推荐,符合系统交互逻辑)
通过NavigationStack/NavigationView的工具栏添加EditButton,让用户手动进入编辑模式后进行拖动:
import SwiftUI struct HomeView: View { struct Item: Identifiable { var id = UUID() var name: String var color: Color } @State var items = [ Item(name: "Item 1", color: .red), Item(name: "Item 2", color: .green), Item(name: "Item 3", color: .blue), Item(name: "Item 4", color: .brown) ] var body: some View { NavigationStack { // iOS 16+;iOS 15及以下替换为NavigationView List { ForEach(items, id: \.id) { item in Text(item.name) .frame(maxWidth: .infinity) .padding() .background(item.color) .foregroundColor(.white) } .onMove(perform: move) } .toolbar { EditButton() // 添加编辑按钮 } } } func move(from source: IndexSet, to destination: Int) { items.move(fromOffsets: source, toOffset: destination) } } struct HomeView_Previews: PreviewProvider { static var previews: some View { HomeView() } }
方案二:强制开启编辑模式
如果希望页面默认允许拖动,无需手动点击编辑按钮,可以通过环境变量强制开启编辑状态:
import SwiftUI struct HomeView: View { struct Item: Identifiable { var id = UUID() var name: String var color: Color } @State var items = [ Item(name: "Item 1", color: .red), Item(name: "Item 2", color: .green), Item(name: "Item 3", color: .blue), Item(name: "Item 4", color: .brown) ] var body: some View { List { ForEach(items, id: \.id) { item in Text(item.name) .frame(maxWidth: .infinity) .padding() .background(item.color) .foregroundColor(.white) } .onMove(perform: move) } .environment(\.editMode, .constant(.active)) // 强制开启编辑模式 } func move(from source: IndexSet, to destination: Int) { items.move(fromOffsets: source, toOffset: destination) } } struct HomeView_Previews: PreviewProvider { static var previews: some View { HomeView() } }
说明:两种方案中你的move方法是正确的,@State修饰的数组在调用move(fromOffsets:toOffset:)后会自动触发视图刷新,保存新的排序状态。
内容的提问来源于stack exchange,提问作者NexusUA
相关产品推荐
相关产品推荐

