Swift didSet для свойства UICollectionViewCell работает, но не обновляет интерфейс

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

class NumberCell: UICollectionViewCell {
    let numberLabel = UILabel()

    override var selected: Bool {
        didSet {
            // Updates as expected
            contentView.backgroundColor = self.selected ? UIColor.redColor() : UIColor.clearColor()
        }
    }

    var number: Int? {
        didSet {
            // Sets and shows the text in the number label as expected when cell is first initialised
            if let number = number {
                numberLabel.text = String(number)
            }
        }
    }

    var isCrossedOut: Bool = false {
        didSet {
            // Sets and displays correct values on initialisation, but later
            // stops updating display
            contentView.backgroundColor = self.isCrossedOut ? UIColor.blackColor() : UIColor.clearColor()
        }
    }

    // ...
}

Выбранное состояние для ячейки обновляется хорошо, но всякий раз, когда я делаю cell.isCrossedOut = trueЯ вижу, как работает код, но я не вижу, как на самом деле меняется цвет фона, хотя кажется, что он использует ту же логику, что и наблюдатель свойства выделения.

Я могу вызвать визуальное обновление, выполнив collectionView.reloadData() (не допускается перезагрузка всего представления коллекции), или collectionView.reloadItemsAtIndexPaths([...]) (более или менее приемлемо, я думаю), но я действительно предпочел бы динамически обновлять пользовательский интерфейс.

РЕДАКТИРОВАТЬ

Вот как я обновляю перечеркнутое свойство:

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath) {
    if shouldBeCrossedOut(indexPath) {
        let cell = self.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! NumberCell
        cell.isCrossedOut = true
    }
}

1 ответ

Решение

Заменить:

self.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! NumberCell

С:

self.collectionView?.cellForItemAtIndexPath(NSIndexPath(forItem: 0, inSection: 0)) as! NumberCell

self.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! NumberCell это метод источника данных, который вы переопределяете, чтобы снабдить представление коллекции ячейкой (т. е. он всегда будет возвращать только что созданную или заново удаленную ячейку, и, следовательно, ячейку, которая в данный момент не отображается на экране). self.collectionView?.cellForItemAtIndexPath(NSIndexPath(forItem: 0, inSection: 0)) as! NumberCell это метод экземпляра, который будет возвращать ссылку на текущую ячейку по заданному пути индекса. Раскадровки не имеют отношения к этой проблеме. Вы можете просмотреть код для игровой площадки с эффективным кодом без каких-либо IB здесь.

Другие вопросы по тегам