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

SwiftUI List中ContextMenu的.disabled修饰符生效异常问题咨询

问题答复

  • 不需要通过DispatchQueue.main.async修改redButton状态,你的问题和线程调度无关,该方法无法修复当前异常。

异常成因

  1. 状态作用域错误:你定义的@State private var redButton是全局属于Test视图的状态,所有ForEach循环生成的列表项共用这一个状态变量,没有和具体的列表项绑定,所有项的ContextMenu禁用逻辑都受同一个值控制。
  2. List复用机制影响:SwiftUI的List底层和UIKit的UITableView一致,自带视图复用逻辑,当你修改全局状态触发视图刷新时,只会更新当前可见/正在被复用的Cell,就会出现禁用状态随机生效、仅部分Cell生效的问题。
    移除List后没有复用逻辑,且仅单个按钮使用该状态,所以不会出现异常。

修复方案

有两种常用的修复方案:

方案1:用集合存储已禁用的项ID

适合需要在父视图统一管理所有列表项状态的场景,将状态和列表项的唯一ID绑定:

struct Test: View {
    // 存储所有已停用的列表项ID
    @State private var deactivatedIds: Set<Int> = []
    
    var body: some View {
        List {
            ForEach(1...10, id: \.self) { number in
                Button {
                    // 点击按钮恢复当前项的可用状态
                    deactivatedIds.remove(number)
                } label: {
                    Text("Button \(number)")
                }.contextMenu {
                    Button {
                        // 停用当前选中的项
                        deactivatedIds.insert(number)
                    } label: {
                        Text("Deactivate")
                    }
                    // 仅当前项ID在禁用集合中时才禁用
                    .disabled(deactivatedIds.contains(number))
                }
            }
        }
    }
}

方案2:抽取独立子视图,状态内部管理

适合列表项状态独立、不需要父视图统一管控的场景,每个子视图自己持有状态,不受复用影响:

struct Test: View {
    var body: some View {
        List {
            ForEach(1...10, id: \.self) { number in
                ListItemView(number: number)
            }
        }
    }
}

// 独立的列表项子视图,自己管理停用状态
struct ListItemView: View {
    let number: Int
    @State private var isDeactivated = false
    
    var body: some View {
        Button {
            isDeactivated = false
        } label: {
            Text("Button \(number)")
        }.contextMenu {
            Button {
                isDeactivated = true
            } label: {
                Text("Deactivate")
            }
            .disabled(isDeactivated)
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.25 21:54:06