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

Swift中如何保存按钮颜色修改状态并实现持久化?

按钮状态持久化实现方案

不用直接存储颜色,以按钮名称作为唯一标识,将每个按钮的选中状态(布尔值)存入UserDefaults是最简洁的解决方案,具体步骤如下:

1. 统一存储键名

先定义常量管理存储键,避免拼写错误:

private let buttonSelectedKeyPrefix = "ButtonSelected_"

2. 修改点击事件:切换样式+保存状态

更新nameButtonTapped方法,在切换颜色的同时,把当前按钮的选中状态写入UserDefaults:

@objc func nameButtonTapped(_ sender: UIButton) {
    guard let buttonTitle = sender.title(for: .normal) else { return }
    
    // 判断当前是否为选中状态
    let isCurrentlySelected = sender.backgroundColor != UIColor(.white)
    
    // 切换按钮样式
    if isCurrentlySelected {
        sender.backgroundColor = UIColor(.white)
        sender.setTitleColor(UIColor(CustomColors.softBlue), for: .normal)
    } else {
        sender.backgroundColor = UIColor(CustomColors.softBlue)
        sender.setTitleColor(.white, for: .normal)
    }
    
    // 保存状态到UserDefaults
    let storageKey = buttonSelectedKeyPrefix + buttonTitle
    UserDefaults.standard.set(!isCurrentlySelected, forKey: storageKey)
}

3. 创建按钮时读取状态,设置初始样式

修改createButton方法(或按钮创建逻辑),从UserDefaults读取历史状态,初始化对应样式:

func createButton(title: String, target: Any?, action: Selector) -> UIButton {
    let button = UIButton(type: .system)
    button.setTitle(title, for: .normal)
    
    // 读取存储的状态,默认未选中
    let storageKey = buttonSelectedKeyPrefix + title
    let isSelected = UserDefaults.standard.bool(forKey: storageKey)
    
    // 根据状态设置初始样式
    if isSelected {
        button.backgroundColor = UIColor(CustomColors.softBlue)
        button.setTitleColor(.white, for: .normal)
    } else {
        button.backgroundColor = UIColor(.white)
        button.setTitleColor(UIColor(CustomColors.softBlue), for: .normal)
    }
    
    // 其他按钮配置(如字体、圆角、内边距等)
    button.addTarget(target, action: action, for: .touchUpInside)
    return button
}

特殊情况处理:按钮名称重复

如果你的names数组存在重复名称,就需要用二维索引作为存储键(比如"ButtonSelected_0_0"对应第一行第一个按钮),调整代码如下:

  • 在viewDidLoad的循环中传递行列索引:
names.enumerated().forEach { rowIndex, rowNames in
    let stackHorizontal = addHorizontalStack()
    rowNames.enumerated().forEach { colIndex, name in
        let button = createButton(title: name, row: rowIndex, col: colIndex, target: self, action: #selector(nameButtonTapped))
        stackHorizontal.addArrangedSubview(button)
    }
    self.stackVertical.addArrangedSubview(stackHorizontal)
}
  • 同步修改createButton和nameButtonTapped中的存储键为buttonSelectedKeyPrefix + "\(row)_\(col)"即可。

内容的提问来源于stack exchange,提问作者ira

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:55:26