суммирование значений на UITableView Cells swift - PullRequest
0 голосов
/ 22 июня 2019

У меня есть TableView в контроллере вида и UILabel в UIViewController тоже. Все хорошо отображается, но я пытаюсь чего-то достичь, и я не могу просто получить за этим логику.

В ячейке табличного представления есть UILabel, в ячейках которого есть значения Int, теперь эти числа меняются. Как получить сумму чисел на метке в ячейке tableView и отобразить на метке в контроллере представления.

Я попытался создать переменную в контроллере UIView и добавить это значение в t, но я не могу этого сделать, потому что не могу сложить это число вместе

любая помощь в том, как это сделать. Спасибо

var total: Double?
func tableView(_ tableView: UITableView, cellForRowAt indexPath: IndexPath) -> UITableViewCell {

        switch indexPath.section {
        case 0:
            let cell = tableView.dequeueReusableCell(withIdentifier: cellId, for: indexPath) as! BrokageCheckoutCell
            cell.configure()
            total = Double("\(cell.subPrice.text!)")
            cell.selectionStyle = .none
            return cell
        case 1:
            let cell = tableView.dequeueReusableCell(withIdentifier: cellId2, for: indexPath) as! OtherCheckoutCell
            cell.configure()
            cell.selectionStyle = .none
            return cell
        default: break
        }
        return UITableViewCell()
    }

Ответы [ 2 ]

1 голос
/ 23 июня 2019

Вы спрашиваете:

как получить сумму чисел на метке в ячейке tableView и отобразить на метке в контроллере вида

InКороче, ты не.Метка в ячейке табличного представления (которая является частью «представления») не является нашим источником данных.Он используется только для отображения отдельных строк.

Например, предположим, что в вашем приложении есть 100 элементов для суммирования, но табличное представление приложения показывает, скажем, только 12 строк за раз.Как улучшение памяти и производительности, iOS будет повторно использовать ячейки, которые прокручиваются вне поля зрения, чтобы показать содержимое для новых строк, которые прокручиваются в поле зрения.Но это означает, что вы не можете сказать «суммировать все содержимое меток в этих 100 ячейках», потому что нет 100 ячеек;их всего 12.

Вместо этого ваше приложение должно ссылаться на свою «модель», ту структуру (например, массив), которую cellForRowAt использовал для определения того, что показывать в данной ячейке табличного представления.Итак, если вы хотите сложить итоговую сумму, вам следует сложить значения в этом массиве, не обращаясь к ячейкам вообще.

А если в вашей ячейке есть элементы управления, позволяющие изменять данные, тоячейка должна инициировать обновление модели.Затем процесс вычисления общей суммы (суммирования значений в массиве) все еще работает.

Итак, давайте рассмотрим пример:

  1. У вас должна быть моделькоторый содержит числа, которые вы хотите сложить.Ваш пример немного неясен, поэтому я создам пример, где каждая строка таблицы содержит имя, цену за единицу и количество:

    struct Item {
        let name: String
        let unitPrice: Decimal
        var quantity: Decimal
    }
    

    В этом примере итоговая сумма для любой данной строки будетбыть количество раз цена за единицу.И общая сумма для всех строк будет суммой всех этих продуктов.

  2. Тогда ваш контроллер представления может иметь массив из них для своей модели:

    var items: [Item] = ...
    
  3. Затем, когда вы захотите обновить метку итоговой суммы, у вас просто будет метод, который рассчитывает количество, умноженное на цену итоговой суммы для каждой строки, а затем суммирует эти значения для расчета общей суммы.Всего.Затем он обновит текстовое поле итоговой суммы соответствующим образом:

    private extension ViewController {
        func updateTotal() {
            let total = items
                .map { $0.quantity * $0.unitPrice }
                .reduce(0, +)
    
            totalLabel.text = totalFormatter.string(for: total)
        }
    }
    

    Обратите внимание, я не получаю эти числа из ячеек (потому что они могут быть использованы повторно), а скорее извлекаю все нужные мне данныеиз модели.

  4. Ключ здесь, однако, в том, что если ваша ячейка, например, позволила пользователю изменить одно из этих значений, вам нужен механизм для обновления контроллера табличного представления.модель.Для этого мы будем использовать протокол:

    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()
        }
    }
    

    И, как вы можете видеть, если можете, после обновлениямодель, она также может автоматически обновлять итоговое значение.

Ключевым моментом здесь является то, что мы никогда не используем ячейки как место, где мы храним данные.Ячейки предназначены только для (а) отображения данных и (б) информирования контроллера представления о наличии каких-либо обновлений, о которых он должен знать.

Мы стремимся к очень четкому разделению обязанностей, когда «представления»предназначены для отображения и взаимодействия с элементами управления, присутствующими на экране, и «модель» содержит все наши данные.

0 голосов
/ 22 июня 2019

Обычный способ сделать это - получить делегат ячейки и сделать ваш ViewController этим делегатом.Всякий раз, когда значение ячейки изменяется, отправьте это значение через делегата, чтобы контроллер представления мог сложить все эти значения.

Это быстрый способ.

Лучший способ сделать этоиметь источник данных для ваших ячеек, который отслеживает значения.Это лучше, поскольку при прокрутке ячеек на экране и за его пределами источник данных может отслеживать значения и восстанавливать их, когда этот путь индекса снова становится видимым.

Поскольку источник данных знает, что это за значения, их просто суммировать.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...