You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.02 13:01:12