Давайте предположим, что ваша Email
модель выглядит примерно так,
class Email {
var message: String
var state: CellState
init(message: String, state: CellState) {
self.message = message
self.state = state
}
}
, где CellState
представляет собой enum
, который представляет states
из cell
- paid, pending, dispute
, т.е.
enum CellState {
case paid, pending, dispute
}
Во-первых, вы не должны писать код конфигурации метода cell
в tableView(_:cellForRowAt:)
. cell's
конфигурация должна быть записана в самом cell
, т.е.
class HomeTableViewCell: UITableViewCell {
var buttonTapHandler: (()->())?
private var email: Email?
func configure(with email: Email) {
self.email = email
switch email.state {
case .paid:
self.backgroundColor = #colorLiteral(red: 0.3411764801, green: 0.6235294342, blue: 0.1686274558, alpha: 1)
case .pending:
self.backgroundColor = #colorLiteral(red: 0.9529411793, green: 0.6862745285, blue: 0.1333333403, alpha: 1)
case .dispute:
self.backgroundColor = #colorLiteral(red: 0.9254902005, green: 0.2352941185, blue: 0.1019607857, alpha: 1)
}
}
@IBAction func onTapPendingButton(_ sender: UIButton) {
if self.email?.state != .pending {
self.email?.state = .pending
self.buttonTapHandler?()
}
}
@IBAction func onTapDisputeButton(_ sender: UIButton) {
if self.email?.state != .dispute {
self.email?.state = .dispute
self.buttonTapHandler?()
}
}
@IBAction func onTapPaidButton(_ sender: UIButton) {
if self.email?.state != .paid {
self.email?.state = .paid
self.buttonTapHandler?()
}
}
}
В приведенном выше коде,
buttonTapHandler
- обрабатывает reload
из cell
всякий раз, когда cell's
state
изменяется после нажатия любой из paid/pending/dispute buttons
. Посмотрим, как это можно использовать дальше.
configure(with:)
- обрабатывает UI
из cell
на основе его current state
.
button tap actions
- изменить cell's
state
, в зависимости от того, на котором нажата button
. Также buttonTapHandler
вызывается для обновления UI
.
Ваш ViewController
выглядит,
class VC: UIViewController, UITableViewDataSource {
var emails = [Email]()
//rest of the code....
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return self.emails.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "cell", for: indexPath) as! HomeTableViewCell
let email = self.emails[indexPath.row]
cell.configure(with: email)
cell.buttonTapHandler = {
DispatchQueue.main.async {
tableView.reloadRows(at: [indexPath], with: .none)
}
}
return cell
}
}
В приведенном выше коде, наиболее важным является то, где мы устанавливаем cell's
buttonTapHandler
, т.е.
cell.buttonTapHandler = {
DispatchQueue.main.async {
tableView.reloadRows(at: [indexPath], with: .none)
}
}
Этот handler
будет вызываться каждый раз, когда вы нажимаете button
в cell
в indexPath
, и этот конкретный cell
будет reloaded
.