如何在多个ViewController中获取UserDefaults开关状态
优化实现方案
1. 重构枚举与UserDefaults封装
把状态枚举和UserDefaults读写逻辑统一封装,避免每个页面重复写操作代码:
// 调整枚举,直接关联存储用的字符串值,并封装状态读写 enum AlertToggleState: String { case on = "On" case off = "Off" // 从UserDefaults获取当前状态的便捷属性 static var current: AlertToggleState { let storedValue = UserDefaults.standard.string(forKey: kAlertsKey) ?? "On" // 默认开启状态 return AlertToggleState(rawValue: storedValue) ?? .on } // 保存当前状态到UserDefaults的方法 func save() { UserDefaults.standard.set(rawValue, forKey: kAlertsKey) // iOS 10+ 无需手动调用synchronize(),系统会自动处理持久化 } // 转成Bool值的计算属性,方便直接用在逻辑判断里 var isActive: Bool { return self == .on } } // 将全局key抽离到公共文件(比如Constants.swift),方便所有页面调用 public let kAlertsKey = "ALERTS_KEY"
2. 简化Settings页面的开关逻辑
替换原来的if-else代码,用封装好的枚举处理:
// 在ViewControllerSettings的开关切换事件中 @IBAction func alertsSwitchToggled(_ sender: UISwitch) { let newState = sender.isOn ? AlertToggleState.on : AlertToggleState.off newState.save() print(sender.isOn ? "on" : "off") }
3. 在其他ViewController中调用状态
在需要获取状态的页面,根据业务需求在合适的生命周期方法里调用:
示例:ViewControllerGUI中读取状态
override func viewWillAppear(_ animated: Bool) { super.viewWillAppear(animated) let alertState = AlertToggleState.current // 根据状态执行业务逻辑,比如控制控件显示/隐藏 if alertState.isActive { // 开启状态的处理逻辑 print("提醒功能已开启") } else { // 关闭状态的处理逻辑 print("提醒功能已关闭") } }
可选:实时监听状态变化
如果需要状态变更时自动刷新所有页面的UI,可搭配通知中心:
- 在枚举的save方法里发送通知:
func save() { UserDefaults.standard.set(rawValue, forKey: kAlertsKey) NotificationCenter.default.post(name: NSNotification.Name("AlertStateChanged"), object: nil) }
- 在其他页面的viewDidLoad中添加监听:
override func viewDidLoad() { super.viewDidLoad() NotificationCenter.default.addObserver(self, selector: #selector(alertStateUpdated), name: NSNotification.Name("AlertStateChanged"), object: nil) } @objc func alertStateUpdated() { let alertState = AlertToggleState.current // 在这里更新页面UI逻辑 } // 页面销毁时移除监听 deinit { NotificationCenter.default.removeObserver(self) }
内容的提问来源于stack exchange,提问作者Emilio CG
相关产品推荐
相关产品推荐

