[英]How to save checkmark status of tableview cell xcode 12 swift 5
我有一個類似於待辦事項列表的簡單應用程序。 我使用了TableViewController
並且能夠為每一行設置復選標記附件類型,還找到了一種保存行數據的方法,以便在應用程序重新啟動時再次顯示項目列表。
我想保存所有行的復選標記狀態。 我在 Stack Overflow 中嘗試了其他查詢,其中大部分已經過時了。
這是我的應用程序代碼
class ViewController: UITableViewController {
var shoppingList = [ShoppingList]()
override func viewDidLoad() {
super.viewDidLoad()
title = "Shopping List"
navigationItem.leftBarButtonItem = UIBarButtonItem(barButtonSystemItem: .add, target: self, action: #selector(addTapped))
navigationItem.rightBarButtonItem = UIBarButtonItem(barButtonSystemItem: .action, target: self, action: #selector(shareTapped))
let clearList = UIBarButtonItem(title: "Clear List", style: .plain, target: self, action: #selector(clearList))
toolbarItems = [clearList]
navigationController?.isToolbarHidden = false
load()
tableView.tableFooterView = UIView() // clears the unused seperator lines
}
@objc func clearList() {
shoppingList.removeAll(keepingCapacity: true)
tableView.reloadData()
}
override func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
shoppingList.count
}
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Word", for: indexPath)
cell.textLabel?.text = shoppingList[indexPath.row].itemName
cell.accessoryType = shoppingList[indexPath.row].checkmarkState ? .checkmark : .none
return cell
}
override func tableView(_ tableView: UITableView, commit editingStyle: UITableViewCell.EditingStyle, forRowAt indexPath: IndexPath) {
if editingStyle == .delete {
shoppingList.remove(at: indexPath.row)
tableView.deleteRows(at: [indexPath], with: .automatic)
}
}
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
if tableView.cellForRow(at: indexPath)?.accessoryType == UITableViewCell.AccessoryType.checkmark {
tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.none
shoppingList[indexPath.row].checkmarkState = false
} else {
tableView.cellForRow(at: indexPath)?.accessoryType = UITableViewCell.AccessoryType.checkmark
shoppingList[indexPath.row].checkmarkState = true
}
save()
}
@objc func addTapped() {
let ac = UIAlertController(title: "New Shopping Item", message: nil, preferredStyle: .alert)
ac.addTextField()
let addAction = UIAlertAction(title: "Add", style: .default) {
[weak self, weak ac] _ in
guard let item = ac?.textFields?[0].text else { return }
self?.addItem(item)
}
ac.addAction(addAction)
ac.addAction(UIAlertAction(title: "Cancel", style: .cancel, handler: nil))
present(ac, animated: true)
}
@objc func shareTapped() {
}
func addItem(_ item: String) {
let itemCapitalised = item.capitalized
shoppingList.insert(ShoppingList(itemName: itemCapitalised), at: 0)
let indexPath = IndexPath(row: 0, section: 0)
tableView.insertRows(at: [indexPath], with: .automatic)
save()
}
func showErrorMessage(errorTitle: String, errorMessage: String) {
let ac = UIAlertController(title: errorTitle, message: errorMessage, preferredStyle: .alert)
ac.addAction(UIAlertAction(title: "Ok", style: .default))
present(ac, animated: true)
}
func save() {
let jsonEncoder = JSONEncoder()
if let savedData = try? jsonEncoder.encode(shoppingList) {
let defaults = UserDefaults.standard
defaults.set(savedData, forKey: "shoppingList")
} else {
print("Failed to save people.")
}
}
func load() {
let defaults = UserDefaults.standard
if let savedList = defaults.object(forKey: "shoppingList") as? Data {
let jsonDecoder = JSONDecoder()
do {
shoppingList = try jsonDecoder.decode([ShoppingList].self, from: savedList)
} catch {
print("Failed to load List")
}
}
}
}
由於您已經在模型中存儲了checkmarkState
,只需添加cell.accessoryType = shoppingList[indexPath.row].checkmarkState ? .checkmark : .none
cell.accessoryType = shoppingList[indexPath.row].checkmarkState ? .checkmark : .none
在tableView(_:cellForRowAt:)
中呈現選中標記狀態。
override func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "Word", for: indexPath)
cell.textLabel?.text = shoppingList[indexPath.row].itemName
cell.accessoryType = shoppingList[indexPath.row].checkmarkState ? .checkmark : .none
return cell
}
此外,還有一種更好的方法來編寫tableView(_:didSelectRowAt:)
:只需反轉checkmarkState
,然后重新加載行。
override func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
shoppingList[indexPath.row].checkmarkState = !shoppingList[indexPath.row].checkmarkState
tableView.reloadRows(at: [indexPath], with: .automatic)
save()
}
盡量記住 MVC 哲學。 永遠不要通過 UI 視圖來確定模型的狀態。 僅由模型確定 UI 視圖的狀態。 當您收到用戶輸入時,直接更改模型,然后相應地重新渲染視圖。 將模型作為唯一的事實來源。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.