App重启后UserDefault保存的主题设置不生效问题求助
问题根源及修复方案
核心问题
- 开关状态被强制覆盖:
viewDidLoad里固定设置theme.setOn(false, animated: false),不管之前保存的是什么,重启后开关都会回到关闭状态,主题逻辑也跟着出错。 - UserDefaultManager设计冗余:
darkmode只是普通变量,没有和UserDefaults关联,完全可以用计算属性直接读写,避免额外的赋值操作。 - 废弃API调用:
synchronize()在iOS 10+已废弃,系统会自动处理UserDefaults的持久化,不需要手动调用。 - 读取逻辑繁琐:用
object(forKey:)再转Bool不如直接用bool(forKey:),后者会自动返回默认值false,无需额外判空。
修正后的代码
1. 重构UserDefaultManager
把darkmode改成计算属性,直接和UserDefaults绑定,简化逻辑:
import Foundation class UserDefaultManager { static let shared = UserDefaultManager() private init() {} // 单例私有化初始化 let keyDarkmode = "UserDefaultDarkmode" private let userDef = UserDefaults.standard var darkmode: Bool { get { userDef.bool(forKey: keyDarkmode) } set { userDef.set(newValue, forKey: keyDarkmode) } } }
2. 修复ViewController逻辑
去掉强制设置开关状态的代码,直接从UserDefaults读取配置并应用:
import UIKit class ViewController: UIViewController { @IBOutlet weak var theme: UISwitch! let userDefaultManager = UserDefaultManager.shared override func viewDidLoad() { super.viewDidLoad() // 从UserDefaults读取保存的主题状态,同步开关和界面 let isDarkMode = userDefaultManager.darkmode theme.setOn(isDarkMode, animated: false) overrideUserInterfaceStyle = isDarkMode ? .dark : .light } @IBAction func themeSwitch(_ sender: UISwitch) { // 保存开关状态到UserDefaults,同时切换主题 userDefaultManager.darkmode = sender.isOn overrideUserInterfaceStyle = sender.isOn ? .dark : .light } }
额外注意事项
如果是多场景App,要在SceneDelegate的scene(_:willConnectTo:options:)方法里也同步主题设置,确保所有场景启动时都能读取到正确的偏好:
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) { guard let windowScene = (scene as? UIWindowScene) else { return } let window = UIWindow(windowScene: windowScene) self.window = window let isDarkMode = UserDefaultManager.shared.darkmode window.overrideUserInterfaceStyle = isDarkMode ? .dark : .light window.rootViewController = ViewController() window.makeKeyAndVisible() }
内容的提问来源于stack exchange,提问作者SwiftLove
相关产品推荐
相关产品推荐

