Затем, когда вы захотите обновить метку итоговой суммы, у вас просто будет метод, который рассчитывает количество, умноженное на цену итоговой суммы для каждой строки, а затем суммирует эти значения для расчета общей суммы.Всего.Затем он обновит текстовое поле итоговой суммы соответствующим образом:
private extension ViewController {
func updateTotal() {
let total = items
.map { $0.quantity * $0.unitPrice }
.reduce(0, +)
totalLabel.text = totalFormatter.string(for: total)
}
}
Обратите внимание, я не получаю эти числа из ячеек (потому что они могут быть использованы повторно), а скорее извлекаю все нужные мне данныеиз модели.
Ключ здесь, однако, в том, что если ваша ячейка, например, позволила пользователю изменить одно из этих значений, вам нужен механизм для обновления контроллера табличного представления.модель.Для этого мы будем использовать протокол:
protocol ItemCellDelegate: class {
func cell(_ cell: ItemCell, didUpdateQuantity quantity: Decimal)
}
class ItemCell: UITableViewCell {
@IBOutlet weak var nameLabel: UILabel!
@IBOutlet weak var quantityTextField: UITextField!
@IBOutlet weak var unitPriceLabel: UILabel!
static let quantityFormatter: NumberFormatter = ...
static let priceFormatter: NumberFormatter = ...
weak var delegate: ItemCellDelegate?
}
Очевидно, что при настройке ячейки контроллер представления будет указывать делегата для обновления текстового поля (или любого другого):
// MARK: Public methods
extension ItemCell {
func configure(name: String, quantity: Decimal, unitPrice: Decimal, delegate: ItemCellDelegate) {
self.delegate = delegate
nameLabel.text = name
quantityTextField.text = ItemCell.quantityFormatter.string(for: quantity)
unitPriceLabel.text = ItemCell.priceFormatter.string(for: unitPrice)
}
}
И когда ItemCell
получает обновления, он просто вызывает делегата:
// MARK: Private methods
private extension ItemCell {
@IBAction func didUpdateQuantity(_ sender: UITextField) {
var quantity: Decimal?
if let text = sender.text, let value = ItemCell.quantityFormatter.number(from: text) {
quantity = value.decimalValue
}
delegate?.cell(self, didUpdateQuantity: quantity ?? 0)
}
}
Затем, когда контроллер представления настроил ячейку, он будет предоставлять себя в качестве делегата:
extension ViewController: UITableViewDataSource {
func tableView(_ tableView: UITableView, numberOfRowsInSection section: Int) -> Int {
return items.count
}
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {
let cell = tableView.dequeueReusableCell(withIdentifier: "ItemCell", for: indexPath) as! ItemCell
let item = items[indexPath.row]
cell.configure(name: item.name, quantity: item.quantity, unitPrice: item.unitPrice, delegate: self)
return cell
}
}
И, конечно, контроллер представления будет соответствовать этому протоколу, чтобы принимать обновления в текстовое поле и обновлять модель:
extension ViewController: ItemCellDelegate {
func cell(_ cell: ItemCell, didUpdateQuantity quantity: Decimal) {
guard let indexPath = tableView.indexPath(for: cell) else { return }
items[indexPath.row].quantity = quantity
updateTotal()
}
}
И, как вы можете видеть, если можете, после обновлениямодель, она также может автоматически обновлять итоговое значение.