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

SwiftUI:Toggle切换时@State的didSet不触发(macOS 10.15环境)

问题原因

你写的didSet不会触发,是因为@State是SwiftUI的属性包装器,你声明的isToggle本质是属性包装器实例,Toggle修改的是它的wrappedValue,不是直接修改这个存储属性,所以不会触发属性观察器。

由于目标版本为 macOS 10.15(对应SwiftUI 1.0,无onChange修饰符),可以使用以下两种兼容方案实现需求:

方案1:自定义Binding实例(轻量首选)

自行构造Toggle绑定的Binding实例,在setter中嵌入你要执行的逻辑即可:

struct ContentView: View {
    @State private var isToggle: Bool = false

    var body: some View {
        Toggle(isOn: Binding(
            get: { isToggle },
            set: { newValue in
                isToggle = newValue
                // 此处写入切换后要触发的所有动作
                print("value did change")
            }
        )) {
            Text("Toggle Label ")
        }
    }
}

方案2:配合ObservableObject使用@Published

如果状态逻辑复杂、需要多页面共享,可以用视图模型实现,@Published修饰的属性可以正常触发didSet:

// 视图模型定义
class ToggleViewModel: ObservableObject {
    @Published var isToggle: Bool = false {
        didSet {
            print("value did change")
        }
    }
}

struct ContentView: View {
    // macOS 10.15 不支持@StateObject,用@ObservedObject即可,建议视图模型实例在上层持有后传入,避免视图刷新时重复初始化
    @ObservedObject private var viewModel = ToggleViewModel()

    var body: some View {
        Toggle(isOn: $viewModel.isToggle) {
            Text("Toggle Label ")
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 16:54:04