Swift didSet在UICollectionViewCell属性上运行,但没有更新UI

时间:2016-02-13 17:36:56

标签: ios swift uicollectionviewcell property-observer

我有一个自定义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 个答案:

答案 0 :(得分:2)

替换:

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 here