Swift didSet on UICollectionViewCell 属性 运行,但未更新 UI

Swift didSet on UICollectionViewCell property running, but not updating UI

我有一个自定义 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([...])(我想或多或少可以接受)来触发视觉更新,但我真的更愿意动态更新 UI。

编辑

我就是这样更新划掉的 属性:

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

替换:

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

与:

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

self.collectionView(collectionView, cellForItemAtIndexPath: indexPath) as! NumberCell 是您重写的数据源方法,用于为集合视图提供一个单元格(即它将始终 return 一个新实例化或新出列的单元格,因此当前不是在屏幕上)。 self.collectionView?.cellForItemAtIndexPath(NSIndexPath(forItem: 0, inSection: 0)) as! NumberCell 是一个实例方法,它将 return 对给定索引路径处的当前单元格的引用。故事板与此问题无关。您可以在没有任何 IB 的情况下查看具有有效代码的游乐场代码 here