我从 Swift 和 Xcode 开始,我试图制作一个简单的应用程序,其中有一堆带有名称的按钮,当我点击一个按钮时,它的背景颜色(白色)和名称的颜色(蓝色)变为相反的颜色,因此背景变为蓝色,名称变为白色。
有没有办法存储该更改,以便当我返回应用程序或关闭它时,这些更改仍然存在? 我见过使用 UserDefaults 进行像这样的小更改,但他们在任何示例中都不使用颜色。
对我的代码可能有用的事情:
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)
}
}
我考虑创建一个布尔变量来检查按钮是否被按下,然后用名称的位置和要存储的变量创建一个字典,当我回到屏幕时,恢复它们并“绘制”按钮,在我看来这看起来很合理,但我不知道如何实施。
您需要执行几个步骤才能使用
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")]
]
}