Поскольку ячейки сняты с хранения и хранение данных внутри подкласса ячеек не будет работать, выберите другую стратегию.Ваш массив items
должен содержать эту информацию о точках , поэтому для этого вам понадобится ваша пользовательская модель.
Прежде всего, создайте массив из ваших пользовательских моделей.,Эта модель будет содержать заголовок и количество точек элемента
struct Item {
var title: String
var points: Int
init(title: String, points: Int = 0) {
self.title = title
self.points = points
}
}
, затем изменить тип вашего массива на массив Item
var items = [Item]()
Теперь в cellForRowAt
установить выходы в зависимостина предмет для индекса
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! PointsCell
let item = items[indexPath.row]
cell.textLabel?.text = item.title
cell.scoreUILabel.text = "\(item.points)"
return cell
}
Но теперь, как справиться с тем, что пользователь нажимает кнопку в ячейке и как увеличить счет?
Одним из решений является создание переменной закрытия в подклассе UITableViewCell
, и когда кнопка будет нажата, это закрытие позволит контроллеру узнать, что кнопка была нажата
class PointsCell: UITableViewCell {
var buttonPressed: (()->Void)?
@IBOutlet weak var scoreUILabel: UILabel!
@IBAction func pointButtonPressed(_ sender: Any) {
buttonPressed?()
}
}
, а затем внутри cellForRowAt
назначить этои скажите, что если нажата кнопка, увеличьте points
этого элемента и перезагрузите эту строку
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell") as! PointsCell
let item = items[indexPath.row]
cell.textLabel?.text = item.title
cell.scoreUILabel.text = "\(item.points)"
cell.buttonPressed = { // this gets called when `buttonPressed?()` is called from cell class
self.items[indexPath.row].points += 1
tableView.reloadRows(at: [indexPath], with: .automatic)
saveData() // optional
}
return cell
}
Обратите внимание, что с этой стратегией вам также нужно будет изменить добавление нового элемента на добавление Item
(кстати, вы можете безопасно принудительно развернуть text
из UITextField
, поскольку это свойство никогда не будет nil
)
self.items.append(Item(title: textfield.text!))
self.saveData()
let indexPath = IndexPath(row: self.items.count - 1, section: 0)
self.listTableView.insertRows(at: [indexPath], with: .automatic)
Также обратите внимание, что для сохранения пользовательской модели в UserDefaults
вам нужно будет кодировать и декодировать свою пользовательскую модель, поэтому вам нужно будет внедрить Codable
в вашу структуру
struct Item: Codable {
//...
}
, а затем для сохранения использовать JSONEncoder
:
func saveData() {
do {
let encoded = try JSONEncoder().encode(items)
UserDefaults.standard.set(encoded, forKey: "items")
} catch { print(error) }
}
и для извлечения, JSONDecoder
:
override func viewDidLoad() {
super.viewDidLoad()
listTableView.dataSource = self
do {
if let data = UserDefaults.standard.data(forKey:"items") {
items = try JSONDecoder().decode([Item].self, from: data)
}
} catch { print(error) }
}
Последнее замечание на будущее: UserDefaults
не предназначены для хранения большого количества данных, и в будущем вы будете программироватьобязательно используйте какую-нибудь базу данных, например Realm
илиродной CoreData
.
Удачи, кстати!;)