UICollectionViewCell повторное использование вызывает неправильное состояние UISwitch - PullRequest
0 голосов
/ 26 января 2019

У меня проблемы с поиском решения этой проблемы. Я использую UISwitch внутри UICollectionViewCell и передаю логическую переменную для включения или выключения.

Условие - только один переключатель должен быть включен одновременно из всех ячеек. Но когда я включаю один переключатель, меняется цвет оттенка другого случайного переключателя, что означает, что его состояние изменилось.

По умолчанию статус переключателя включен в раскадровке, и даже если я установил его, ничего не изменится.

Я не мог понять, почему это происходит.

image

Вот мой код для cellForItemAtIndexPath

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AddEditItemPopupView.cellId, for: indexPath) as! DiscountCollectionViewCell
        cell.delegate = self

        let currentDiscount = allDiscounts[indexPath.item]
        let shouldApplyDiscount = updatedDiscountId == currentDiscount.id
        cell.updateCellWith(data: currentDiscount, applyDiscount: shouldApplyDiscount)
        return cell
    }

И код для класса ячейки

func updateCellWith(data: DiscountModel, applyDiscount: Bool) {
        let name = data.title.replacingOccurrences(of: "Discount ", with: "")
        self.titleLabel.text = String(format: "%@ (%.2f%%)", name, data.value)
        self.switchApply.isOn = applyDiscount
        self.switchApply.tag = data.id
    }

Источник данных содержит объекты DiscountModel, которые выглядят так:

{
    id: Int!
    title: String!
    value: Double!
}

Переключить значение измененного метода внутри класса ячейки:

@IBAction func switchValueChanged(_ sender: UISwitch) {
        if sender.isOn {
            self.delegate?.switchValueDidChangeAt(index: sender.tag)
        }
        else{
            self.delegate?.switchValueDidChangeAt(index: 0)
        }
    }

Метод делегата внутри класса контроллера представления:

func switchValueDidChangeAt(index: Int) {
        self.updatedDiscountId = index
        self.discountCollectionView.reloadData()
    }

1 Ответ

0 голосов
/ 26 января 2019

Есть несколько улучшений, которые я бы предложил в вашем коде;

  • Перезагрузка всего представления коллекции - это немного дробовика
  • Поскольку возможно, что не будетприменяется скидка, вам, вероятно, следует использовать дополнительную для выбранной скидки, а не «0»
  • Использование Tag часто проблематично

Я бы использовал что-то вроде:

var currentDiscount: DiscountModel? = nil

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: AddEditItemPopupView.cellId, for: indexPath) as! DiscountCollectionViewCell
    cell.delegate = self

    let item = allDiscounts[indexPath.item]
    self.configure(cell, forItem: item)

    return cell
}

func configure(_ cell: DiscountCollectionViewCell, forItem item: DiscountModel) {
    cell.switchApply.isOn = false
    let name = item.title.replacingOccurrences(of: "Discount ", with: "")
    self.titleLabel.text = String(format: "%@ (%.2f%%)", name, item.value)

    guard let selectedDiscount = self.currentDiscount else {
        return
    }

    cell.switchApply.isOn = selectedDiscount.id == item.id
}

func switchValueDidChangeIn(cell: DiscountCollectionViewCell, to value: Bool) {
    if value {
        if let indexPath = collectionView.indexPath(for: cell) {
           self.currentDiscount = self.allDiscounts[indexPath.item]
        }
    } else {
        self.currentDiscount = nil
    }
    for indexPath in collectionView.indexPathsForVisibleItems {
        if let cell = collectionView.cellForItem(at: indexPath) {
            self.configure(cell, forItem: self.allDiscounts[indexPath.item])
        }
    }
}

В вашей камере:

@IBAction func switchValueChanged(_ sender: UISwitch) {
    self.delegate?.switchValueDidChangeIn(cell:self, to: sender.isOn)
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...