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

iOS16中SwiftUI onMove重排控件不显示及长按禁用需求

解决iOS16 List编辑模式下重排控件不显示问题

问题说明

需求是仅在编辑模式激活时启用列表行的移动功能,同时禁止iOS16中通过长按列表行触发移动操作。当前遇到的问题是:点击编辑按钮激活编辑模式后,列表行的重排控件(拖动图标)不会自动显示,必须将该行滚出屏幕再滚回来才会出现。

问题原因

原代码中使用了独立的enableMove变量控制onMove的可用性,但该变量与EditMode状态的更新未绑定,导致SwiftUI无法感知到需要刷新列表的ForEach部分,进而没有触发重排控件的渲染。

解决方案

直接通过EditMode的状态控制onMove的启用,无需额外变量。这样编辑模式切换时,SwiftUI会自动刷新列表,立即显示重排控件,同时也能实现非编辑模式下禁用长按移动的需求。

修改要点

  • 删除独立的enableMove状态变量,直接用editModeCurrent == .active判断是否启用移动功能
  • 调整onMove的perform参数,绑定到EditMode的状态
  • 简化编辑按钮逻辑,只负责切换EditMode的状态

完整修改后的代码

struct ContentView: View {
    
    @State private var editModeCurrent: EditMode = .inactive
    
    var body: some View {
        NavigationSplitView {
            
        } detail: {
            List {                    
                ForEach(0..<200) { i in
                    Button {
                        
                    } label: {
                        CustomRow(i: i)
                    }
                }
                // 直接通过EditMode状态控制onMove是否启用
                .onMove(perform: editModeCurrent == .active ? move : nil)
                .onDelete(perform: removeRows)
            }
            .listStyle(.plain)
            .environment(\.editMode, $editModeCurrent)
            .toolbar {
                editButton
            }
        }
        .navigationTitle("Oceans")
    }
    
    private var editButton: some View {
        Button {
            editModeCurrent = editModeCurrent == .inactive ? .active : .inactive
        } label: {
            Text(editModeCurrent == .inactive ? "Edit" : "Done")
                .foregroundColor(.red)
        }
    }
    
    func move(from source: IndexSet, to destination: Int) {
        
    }
    
    func removeRows(at offsets: IndexSet) {
        
    }
}

struct CustomRow: View {
    let i: Int
    
    var body: some View {
        HStack {
            Text("\(i)")
            
            Spacer()
            
            Image(systemName: "minus.circle")
        }
    }
}

额外说明

修改后不仅解决了重排控件不自动显示的问题,还天然实现了“仅编辑模式下允许移动”的需求:非编辑模式时onMove的perform为nil,iOS16的长按手势不会触发移动操作;激活编辑模式后,列表会立即刷新并显示重排控件,无需滚动屏幕。

内容的提问来源于stack exchange,提问作者User95797654974

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.14 14:28:13