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 здесь.