如何在Xcode 14.2中保存App明暗模式的用户偏好
如何保存iOS App的明暗模式偏好,重启后仍生效(Xcode 14.2)
实现思路
利用UserDefaults存储用户选择的模式偏好,在App启动或视图加载时读取存储的值,恢复对应的界面风格。
1. 修改模式切换按钮代码
在切换明暗模式的同时,将选择保存到UserDefaults:
@IBAction func darkButton(_ sender: Any) { overrideUserInterfaceStyle = .dark UserDefaults.standard.set("dark", forKey: "userInterfaceMode") } @IBAction func lightButton(_ sender: Any) { overrideUserInterfaceStyle = .light UserDefaults.standard.set("light", forKey: "userInterfaceMode") }
2. 在视图加载时恢复用户偏好
在viewDidAppear方法中读取存储的模式值,设置对应的界面风格:
override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) // 读取保存的模式偏好 let savedMode = UserDefaults.standard.string(forKey: "userInterfaceMode") if savedMode == "dark" { overrideUserInterfaceStyle = .dark } else { // 默认使用浅色模式,也可根据系统设置调整 overrideUserInterfaceStyle = .light } // 其他业务逻辑... }
完整修正后的代码
import UIKit class ViewController: UIViewController { // 所有输入文本框 @IBOutlet weak var machineODInputText: UITextField! @IBOutlet weak var pipeODInputText: UITextField! @IBOutlet weak var pipeLengthInputText: UITextField! @IBOutlet weak var driveLengthInputText: UITextField! @IBOutlet weak var muckUpInputText: UITextField! @IBOutlet weak var jackingSpeedInputText: UITextField! @IBOutlet weak var weightOfBenoBagInputText: UITextField! @IBOutlet weak var noOfBenoBagsInputText: UITextField! @IBOutlet weak var benoQtyForTanksInputText: UITextField! @IBOutlet weak var noOfBenoBagsPerPalletInputText: UITextField! // 所有结果文本框 @IBOutlet weak var lubricationPumpSpeedResult: UILabel! @IBOutlet weak var volumePerMeterResult: UILabel! @IBOutlet weak var volumePerPipeResult: UILabel! @IBOutlet weak var volumeForDriveResult: UILabel! @IBOutlet weak var benoQtyForLubricationResult: UILabel! @IBOutlet weak var benoQtyForDriveResult: UILabel! @IBOutlet weak var noOfPalletsForDriveResult: UILabel! // 模式切换按钮 @IBAction func lightButton(_ sender: Any) { overrideUserInterfaceStyle = .light UserDefaults.standard.set("light", forKey: "userInterfaceMode") } @IBAction func darkButton(_ sender: Any) { overrideUserInterfaceStyle = .dark UserDefaults.standard.set("dark", forKey: "userInterfaceMode") } @IBAction func calculateButton(_ sender: Any) { let formatter = NumberFormatter() formatter.numberStyle = .decimal formatter.maximumFractionDigits = 0 let formatter2 = NumberFormatter() formatter2.numberStyle = .decimal formatter2.maximumFractionDigits = 2 let pi = Double.pi / 4 let TBMOD = (Double(machineODInputText.text!) ?? 1) / 1000.0 let pipeOD = (Double(pipeODInputText.text!) ?? 1) / 1000.0 let muckup = (Double(muckUpInputText.text!) ?? 2.5) let advanceSpeed = (Double(jackingSpeedInputText.text!) ?? 1) let volPerPipe = (Double(pipeLengthInputText.text!) ?? 1) let volForDrive = (Double(driveLengthInputText.text!) ?? 1) let noOfBenoBagsForLub = (Double(noOfBenoBagsInputText.text!) ?? 1) let weightOfEachBenoBag = (Double(weightOfBenoBagInputText.text!) ?? 1) let amountOfBenoBagsInTamks = (Double(benoQtyForTanksInputText.text!) ?? 1) let noOfBenoBagsPerPallet = (Double(noOfBenoBagsPerPalletInputText.text!) ?? 1) // 计算每米体积(升/米) let volPerMtrResults1 = ((pi * (TBMOD) * (TBMOD)) - (pi * (pipeOD) * (pipeOD))) * muckup * 1000 let volPerMtrResult = formatter.string(from: NSNumber(value: volPerMtrResults1)) volumePerMeterResult.text = volPerMtrResult // 计算润滑泵流量(升/分钟) let pumpCapacityResults1 = (advanceSpeed / 1000) * volPerMtrResults1 let lubPerMtrResult = formatter.string(from: NSNumber(value: pumpCapacityResults1)) lubricationPumpSpeedResult.text = lubPerMtrResult // 计算单根管道体积(立方米/根) let volPerPipeResults1 = (volPerMtrResults1 / 1000) * volPerPipe let volPerPipeResult = formatter2.string(from: NSNumber(value: volPerPipeResults1)) volumePerPipeResult.text = volPerPipeResult // 计算驱动段总容积(立方米) let volPerDriveResults1 = (volPerMtrResults1 / 1000) * volForDrive let volPerDriveResult = formatter.string(from: NSNumber(value: volPerDriveResults1)) volumeForDriveResult.text = volPerDriveResult // 计算润滑所需膨润土量 let ammountOfBenoForLubResults1 = noOfBenoBagsForLub * volPerDriveResults1 * weightOfEachBenoBag let ammountOfBenoForLubResult = formatter.string(from: NSNumber(value: ammountOfBenoForLubResults1)) benoQtyForLubricationResult.text = ammountOfBenoForLubResult // 计算驱动段总膨润土量 let amountOfBenoForDriveResults1 = ammountOfBenoForLubResults1 + (amountOfBenoBagsInTamks * 1000) let amountOfBenoForDriveResult = formatter.string(from: NSNumber(value: amountOfBenoForDriveResults1)) benoQtyForDriveResult.text = amountOfBenoForDriveResult // 计算驱动段所需托盘数 let ammountOfBenoPerPalletResults1 = amountOfBenoForDriveResults1 / weightOfEachBenoBag / noOfBenoBagsPerPallet let ammountOfBenoPerPalletResult = formatter2.string(from: NSNumber(value: ammountOfBenoPerPalletResults1)) noOfPalletsForDriveResult.text = ammountOfBenoPerPalletResult UserDefaults.standard.set(machineODInputText.text, forKey: "TBMOD") UserDefaults.standard.set(pipeODInputText.text, forKey: "pipeOD") UserDefaults.standard.set(muckUpInputText.text, forKey: "muckUp") UserDefaults.standard.set(jackingSpeedInputText.text, forKey: "speed") UserDefaults.standard.set(pipeLengthInputText.text, forKey: "pipeLength") UserDefaults.standard.set(driveLengthInputText.text, forKey: "driveLength") UserDefaults.standard.set(noOfBenoBagsInputText.text, forKey: "noOfBenoBags") UserDefaults.standard.set(weightOfBenoBagInputText.text, forKey: "weightOfBenoBag") UserDefaults.standard.set(benoQtyForTanksInputText.text, forKey: "benoQtyForTanks") UserDefaults.standard.set(noOfBenoBagsPerPalletInputText.text, forKey: "benoBagsPerPallet") } // 为键盘添加带“完成”按钮的工具栏(toolbar.swift文件) override func viewDidLoad() { super.viewDidLoad() machineODInputText.inputAccessoryView = toolBar() pipeODInputText.inputAccessoryView = toolBar() pipeLengthInputText.inputAccessoryView = toolBar() driveLengthInputText.inputAccessoryView = toolBar() muckUpInputText.inputAccessoryView = toolBar() jackingSpeedInputText.inputAccessoryView = toolBar() weightOfBenoBagInputText.inputAccessoryView = toolBar() noOfBenoBagsInputText.inputAccessoryView = toolBar() benoQtyForTanksInputText.inputAccessoryView = toolBar() noOfBenoBagsPerPalletInputText.inputAccessoryView = toolBar() } // 加载历史数据到输入框 override func viewDidAppear(_ animated: Bool) { super.viewDidAppear(animated) if let a = UserDefaults.standard.object(forKey: "TBMOD") as? String { machineODInputText.text = a } if let a = UserDefaults.standard.object(forKey: "pipeOD") as? String { pipeODInputText.text = a } if let a = UserDefaults.standard.object(forKey: "muckUp") as? String { muckUpInputText.text = a } if let a = UserDefaults.standard.object(forKey: "speed") as? String { jackingSpeedInputText.text = a } if let a = UserDefaults.standard.object(forKey: "pipeLength") as? String { pipeLengthInputText.text = a } if let a = UserDefaults.standard.object(forKey: "driveLength") as? String { driveLengthInputText.text = a } if let a = UserDefaults.standard.object(forKey: "noOfBenoBags") as? String { noOfBenoBagsInputText.text = a } if let a = UserDefaults.standard.object(forKey: "weightOfBenoBag") as? String { weightOfBenoBagInputText.text = a } if let a = UserDefaults.standard.object(forKey: "benoQtyForTanks") as? String { benoQtyForTanksInputText.text = a } if let a = UserDefaults.standard.object(forKey: "benoBagsPerPallet") as? String { noOfBenoBagsPerPalletInputText.text = a } // 加载用户上次选择的明暗模式 let savedMode = UserDefaults.standard.string(forKey: "userInterfaceMode") if savedMode == "dark" { overrideUserInterfaceStyle = .dark } else { overrideUserInterfaceStyle = .light } machineODInputText.clearsOnBeginEditing = true pipeODInputText.clearsOnBeginEditing = true pipeLengthInputText.clearsOnBeginEditing = true driveLengthInputText.clearsOnBeginEditing = true muckUpInputText.clearsOnBeginEditing = true jackingSpeedInputText.clearsOnBeginEditing = true weightOfBenoBagInputText.clearsOnBeginEditing = true noOfBenoBagsInputText.clearsOnBeginEditing = true benoQtyForTanksInputText.clearsOnBeginEditing = true noOfBenoBagsPerPalletInputText.clearsOnBeginEditing = true } }
额外说明
UserDefaults是轻量级存储方案,适合保存这类用户偏好设置- 如果需要支持跟随系统自动切换,可以在无保存值时,使用
UITraitCollection.current.userInterfaceStyle获取系统当前模式 - 选择在
viewDidAppear中恢复模式,因为该方法在视图每次显示时都会调用,包括App重启后首次加载
内容的提问来源于stack exchange,提问作者user2253720
相关产品推荐
相关产品推荐

