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

SwiftUI中FamilyActivityPicker的onChange事件未触发问题求助

问题分析与解决

核心问题:SwiftUI无法感知Model属性变化

你的代码里FamilyControlModel未遵循ObservableObject协议,也未用@Published标记selection属性。SwiftUI的视图更新、onChange回调完全依赖可观察对象的属性变更通知——这就是为什么视图的onChange没触发,但selection的didSet能执行:Picker确实修改了selection,但视图根本没收到属性变化的通知。

修复步骤

  1. 让Model成为可观察对象
    修改FamilyControlModel,添加协议遵循和属性标记,让SwiftUI能追踪selection的变化:

    class FamilyControlModel: ObservableObject {
        static let shared = FamilyControlModel()
        @Published var selection = FamilyActivitySelection() 
    }
    

    注意:Swift语法中类关键字是小写class,原代码的Class是语法错误。

  2. 规范onChange逻辑
    修复Model后,onChange(of: model.selection)就能正常触发。同时建议避免强制解包,改用可选绑定保证代码安全:

    .onChange(of: model.selection) { newSelection in
        print("on change")
        if let data = try? JSONEncoder().encode(newSelection),
           let strData = data.base64EncodedString() {
            print(strData)
        }
    }
    
  3. 解决didSet多次触发的问题
    FamilyActivityPicker内部可能因初始化、用户选择的中间状态多次更新selection,属于控件正常行为。如果只需处理最终选择结果,可在didSet中添加旧值判断:

    @Published var selection = FamilyActivitySelection() {
        didSet {
            guard selection != oldValue else { return }
            // 仅当值真正变化时执行逻辑
        }
    }
    

额外注意点

  • @StateObject搭配单例shared的用法是合理的,它会确保Model实例在视图生命周期内被正确持有。
  • 确保FamilyActivitySelection遵循Codable协议,否则encoder.encode会执行失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.15 02:49:59