如何在 Swift 中保存按钮颜色的变化?

问题描述 投票:0回答:1

我从 Swift 和 Xcode 开始,我试图制作一个简单的应用程序,其中有一堆带有名称的按钮,当我点击一个按钮时,它的背景颜色(白色)和名称的颜色(蓝色)变为相反的颜色,因此背景变为蓝色,名称变为白色。

有没有办法存储该更改,以便当我返回应用程序或关闭它时,这些更改仍然存在? 我见过使用 UserDefaults 进行像这样的小更改,但他们在任何示例中都不使用颜色。

对我的代码可能有用的事情:

  • 我的颜色是自定义颜色,因此它们存储在名为 CustomColor 的不同文件中,该文件是一个结构体,如下所示:
    static let softBlue = Color("softBlue")
  • 我的名字存储在数组的数组中,看起来像这样:
let names = [
        ["Liam", "Noah", "Oliver", "James"],
        ["Elijah", "William", "Lucas", "Mateo"],
        ["....]
]
  • 我的其余代码如下:
let names = ....

 override func viewDidLoad() {
        super.viewDidLoad()
                
        self.stackVertical.arrangedSubviews.forEach { $0.removeFromSuperview() }
        
        nomes.forEach {
            let stackHorizontal = addHorizontalStack()
            
            $0.forEach { name in
                let button = createButton(title: name, target: self, action: #selector(nameButtonTapped))
                stackHorizontal.addArrangedSubview(button)
            }
            self.stackVertical.addArrangedSubview(stackHorizontal)
        }

    }
 
    @objc func nameButtonTapped(_ sender: UIButton) {
        if sender.backgroundColor == UIColor(.white) {
            sender.backgroundColor = UIColor(CustomColors.softBlue)
            sender.setTitleColor(.white, for: .normal)
        } else {
            sender.backgroundColor = UIColor(.white)
            sender.setTitleColor(UIColor(CustomColors.softBlue), for: .normal)
        }
        
    }

我考虑创建一个布尔变量来检查按钮是否被按下,然后用名称的位置和要存储的变量创建一个字典,当我回到屏幕时,恢复它们并“绘制”按钮,在我看来这看起来很合理,但我不知道如何实施。

swift button colors savechanges
1个回答
0
投票

您需要执行几个步骤才能使用

UserDefault
实现此目的。根据您的评论,这是多项选择,因此您必须保存所有按钮状态。您可以通过为这些按钮设置
tag
,然后使用
names
数组进行映射来完成此操作。不过,我想制作一个子按钮

class Person: Codable {
    private(set) var name: String
    private(set) var isSelected: Bool = false
    
    init(_ name: String) {
        self.name = name
    }
    
    func set(isSelected: Bool) {
        self.isSelected = isSelected
    }
}

class PersonButton: UIButton {
    private(set) var data: Person!
    
    override var isSelected: Bool {
        didSet {
            data.set(isSelected: isSelected)
        }
    }
    
    override init(frame: CGRect) {
        super.init(frame: .zero)
    }
    
    required init?(coder: NSCoder) {
        super.init(coder: coder)
    }
    
    func set(data: Person) {
        self.data = data
    }
}

然后在您的 ViewController 中,为这些按钮创建一个构造函数以及一个用于切换其状态的函数

...
private func createButton(with person: Person) -> UIButton {
    let button = PersonButton()
    button.set(data: person)
    button.setTitle(person.name, for: .normal)
    button.setTitleColor(.white, for: .selected)
    button.setTitleColor(.black, for: .normal)
    button.backgroundColor = person.isSelected ? .red : .blue
    button.isSelected = person.isSelected
    return button
}

@objc private func buttonTapped(_ sender: PersonButton) {
    sender.isSelected.toggle()
    sender.backgroundColor = sender.isSelected ? .red : .blue
}

还有

save
函数用于保存按钮状态和
read
函数用于从 UserDefault 加载数据。还有一个函数保证
names
不应该为空。

private func save() {
    let encoder = JSONEncoder()
    do {
        let jsonData = try encoder.encode(names.self)
        let json = String(data: jsonData, encoding: .utf8)
        UserDefaults.standard.set(json, forKey: "Cache")
    } catch {
        //TODO: throw error if needed
    }
}
    
private func read() {
    guard
        let json = UserDefaults.standard.string(forKey: "Cache"), !json.isEmpty,
        let jsonData = json.data(using: .utf8)
    else {
        initDataIfNeeded()
        return
    }
    let decoder = JSONDecoder()
    do {
        let group = try decoder.decode([[Person]].self, from: jsonData)
        self.group = group
    } catch {
        initDataIfNeeded()
        //TODO: throw error if needed
    }
}

private func initDataIfNeeded() {
    names = [
        [.init("Liam"), .init("Noah"), .init("Oliver"), .init("James")],
        [.init("Elijah"), .init("William"), .init("Lucas"), .init("Mateo")]
    ]
}
© www.soinside.com 2019 - 2024. All rights reserved.