SwiftUI中FamilyActivityPicker的onChange事件未触发问题求助
问题分析与解决
核心问题:SwiftUI无法感知Model属性变化
你的代码里FamilyControlModel未遵循ObservableObject协议,也未用@Published标记selection属性。SwiftUI的视图更新、onChange回调完全依赖可观察对象的属性变更通知——这就是为什么视图的onChange没触发,但selection的didSet能执行:Picker确实修改了selection,但视图根本没收到属性变化的通知。
修复步骤
让Model成为可观察对象
修改FamilyControlModel,添加协议遵循和属性标记,让SwiftUI能追踪selection的变化:class FamilyControlModel: ObservableObject { static let shared = FamilyControlModel() @Published var selection = FamilyActivitySelection() }注意:Swift语法中类关键字是小写
class,原代码的Class是语法错误。规范
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) } }解决
didSet多次触发的问题FamilyActivityPicker内部可能因初始化、用户选择的中间状态多次更新selection,属于控件正常行为。如果只需处理最终选择结果,可在didSet中添加旧值判断:@Published var selection = FamilyActivitySelection() { didSet { guard selection != oldValue else { return } // 仅当值真正变化时执行逻辑 } }
额外注意点
@StateObject搭配单例shared的用法是合理的,它会确保Model实例在视图生命周期内被正确持有。- 确保
FamilyActivitySelection遵循Codable协议,否则encoder.encode会执行失败。
内容的提问来源于stack exchange,提问作者TommyBs
相关产品推荐
相关产品推荐

