Передать значение в массив для tableView

swift

#1

Всем привет!
У меня есть tableView, это экран корзины, в котором магазины разбиты по секциям. В секциях ячейки с товаром. В этих ячейках есть UILabel цены, UILabel кол-ва одного товара в корзине и UILabel, суммирующий цена * кол-во. Также есть две кнопки для уменьшения и прибавления количества на 1. Пример кода -

    var count: Float =  Float(cell.countLabel.text!)!
    guard Int(count) > 1 else { return }
    var shortPrice = cell.newPrice.text
    shortPrice?.removeLast(2)
    let floatPrice = Float(shortPrice!)
    count -= 1
    let newSumShortPrice = floatPrice! * count
    cell.countLabel.text = String(Int(count))
    cell.summPrice.text = "\(newSumShortPrice) ₽"

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

Структура массива такая (основное все убрал, дабы не мешало. Оставил только нужное) -

struct ViewModel {
    var name: String?
    var offers: [Offers]?
}


   struct Offers : Mappable {
        var count : Int?
        var fullPrice : String?
        var shortPrice : String?
    }

var purchasesViewModel = [PurchaseList.Fetch.ViewModel]()
На сколько я понимаю, необходимо передать значения в массив и использовать tableView.reloadData()

Но как передать новое значение count в массив?


#2

Создайте в ячейке делегат с двумя методами plusOne, minusOne.
Входные параметры у них будут IndexPath.
Когда будете заполнять ячейку данными, передавайте в ячейку indexPath.
При нажатии на эти две кнопки, вызывайте соответствующий метод делегата и передавайте в него indexPath, который хранит ячейка.
В самом VC вы должны реализвать эти 2 метода делегата и через полученный indexPath в них будете менять нужные данные в массиве
purchasesViewModel[indexPath.section].offers[indexPath.row] += 1
или
purchasesViewModel[indexPath.section].offers[indexPath.row] -= 1
И после этого reload.
Хотя если визуально у вас уже все меняется, то релоад можно не делать.

P.S. вам останется лишь предусмотреть логику когда товар будет удален таким образом.


#3

Привет! Благодарю за ответ! Сейчас попытаюсь реализовать. Копипастну код сюда, как сделаю.


#4

Пошагово:

Прописал протокол -

protocol ItemTableViewCellDelegate: class {

func didTapButtonMinus(cell: ItemTableViewCell)
func didTapButtonPlus(cell: ItemTableViewCell)
}

В UTableViewCell -

weak var cellDelegate: ItemTableViewCellDelegate?

@IBAction func plusTapped( _ sender: Any ) {
cellDelegate?.didTapButtonPlus(cell: self)
}

@IBAction func minusTapped( _ sender: Any ) {
cellDelegate?.didTapButtonPlus(cell: self)
}

В ViewController -

extension PurchaseListViewController: ItemTableViewCellDelegate {
    
    func didTapButtonMinus(cell: ItemTableViewCell) {
        if let indexPath = tableView.indexPath(for: cell) {
            purchasesViewModel[indexPath.section].offers![indexPath.row].count! -= 1
            changePriceTextForCells(cell: cell, buttonType: .minus)
        }
    }
    
    func didTapButtonPlus(cell: ItemTableViewCell) {
        if let indexPath =  tableView.indexPath(for: cell) {
            purchasesViewModel[indexPath.section].offers![indexPath.row].count! += 1
            changePriceTextForCells(cell: cell, buttonType: .plus)
        }    
    }
}

Не забыть прописать в методе cellForRowAt - cell.cellDelegate = self

RexHunt, как всегда огромное спасибо!


#5

Кстати, я не просто так написал про reloadData() :slight_smile: Это связано со вчерашним вопросом, про секции. Там же тоже суммирующая цена по магазину. Поэтому, если не добавить метод, то не перерасчитается сумма.


#6

Точно. Я уже забыл про секции. В таком случае релоад нужен.


Как удалить секцию в UITableView