Swift iOS:选中BEMCheckBox时UserDefaults保存账号密码失效问题
问题排查与解决方案
看起来你的核心问题是复选框选中时的保存逻辑没有被正确触发,我帮你梳理几个关键问题和修复方案:
1. 未遵循BEMCheckBoxDelegate协议
你设置了box1.delegate = self,但你的ViewController没有明确遵循BEMCheckBoxDelegate协议,导致复选框点击时的代理方法didTap(_:)根本不会被调用。这是最关键的问题!
2. viewDidLoad方法的调用顺序错误
你在viewDidLoad里先调用了didTap(box1),然后才设置代理,最后调用checkSavedData()。这个顺序会导致:
- 页面加载时就触发一次保存/删除操作,可能覆盖之前的正确数据
- 代理设置晚于主动调用,逻辑混乱
3. 键名定义的小问题
keys结构体里的boxBool用了var,它作为固定的键名应该是常量,改成let更合理。
修正后的完整代码
import UIKit import BEMCheckBox class ViewController: UIViewController { let defaults = UserDefaults.standard @IBOutlet weak var box1: BEMCheckBox! @IBOutlet weak var emailTextField: UITextField! @IBOutlet weak var passwordTextField: UITextField! struct Keys { static let emailKey = "emailTextField" static let passwordKey = "passwordTextField" static let boxBool = "boxBool" // 改为let常量,符合命名规范 } override func viewDidLoad() { super.viewDidLoad() box1.delegate = self // 先设置代理,确保点击事件能被监听 checkSavedData() // 再恢复之前保存的数据 // 移除主动调用didTap的代码,避免页面加载时误触发保存/删除逻辑 } // 确保这个方法是BEMCheckBoxDelegate的代理方法 func didTap(_ checkBox: BEMCheckBox) { if checkBox.on { rememberMyEmailandPassword() } else { defaults.removeObject(forKey: Keys.emailKey) defaults.removeObject(forKey: Keys.passwordKey) defaults.set(false, forKey: Keys.boxBool) // 直接设为false比移除键更稳妥 } } func rememberMyEmailandPassword() { // 可选值绑定,避免保存空的邮箱或密码 guard let email = emailTextField.text, !email.isEmpty, let password = passwordTextField.text, !password.isEmpty else { // 这里可以添加用户提示,比如"请输入完整的邮箱和密码" return } defaults.set(email, forKey: Keys.emailKey) defaults.set(password, forKey: Keys.passwordKey) defaults.set(box1.on, forKey: Keys.boxBool) } func checkSavedData() { // 用string(forKey:)代替value(forKey:),类型转换更安全直接 let email = defaults.string(forKey: Keys.emailKey) ?? "" let password = defaults.string(forKey: Keys.passwordKey) ?? "" let boxBoolean = defaults.bool(forKey: Keys.boxBool) emailTextField.text = email passwordTextField.text = password box1.on = boxBoolean } } // 必须添加这个扩展,让ViewController遵循BEMCheckBoxDelegate协议,代理方法才能生效 extension ViewController: BEMCheckBoxDelegate {}
额外优化点说明
- 调整了变量和结构体的命名,符合Swift的命名规范(小写开头的实例变量,大写开头的结构体)
- 在保存逻辑里添加了空值判断,避免保存无效的空内容
- 取消选中时直接设置复选框状态为
false,而不是移除键,让读取逻辑更稳定 - 用
string(forKey:)替代value(forKey:),减少不必要的类型转换
你可以试试这个修正后的代码,应该就能正常保存和恢复用户的邮箱、密码以及复选框状态了。
内容的提问来源于stack exchange,提问作者Nawaf
相关产品推荐
相关产品推荐

