You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 04:52:47