首先西潘,需求是做一個(gè)選擇顏色的小組件。如下圖所示
需要滑動(dòng)展示哨颂,8種顏色喷市,一頁(yè)顯示4個(gè),共兩頁(yè)威恼。
我選擇了UICollectionView來(lái)做品姓。因?yàn)轭伾珗D片是直接用Graphics畫的,就直接把繪制出來(lái)的CGImage賦值給了UICollectionViewCell的contentView.layer.contents屬性箫措。
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: UICollectionViewCell.reuseIdentifier, for: indexPath)
let colorType = viewModel!.colors[indexPath.section][indexPath.item]
if colorType == viewModel!.selectedColor {
cell.contentView.layer.contents = cgImage(for: .selected, colorType: colorType)
}else {
cell.contentView.layer.contents = cgImage(for: .normal, colorType: colorType)
}
return cell
}
主要的代理方法如下:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.contentView.layer.contents = cgImage(for: .selected,
colorType: viewModel!.colors[indexPath.section][indexPath.item])
viewModel!.selectedColor = viewModel!.colors[indexPath.section][indexPath.item]
}
func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
let cell = collectionView.cellForItem(at: indexPath)
cell?.contentView.layer.contents = cgImage(for: .normal,
colorType: viewModel!.colors[indexPath.section][indexPath.item])
}
看上去很完美腹备,我也是這么認(rèn)為的〗锫可當(dāng)我愉快的選來(lái)選去的時(shí)候植酥,出現(xiàn)了這種情況:
我第一反應(yīng)是惧互,難道didDeselect方法沒(méi)有執(zhí)行?經(jīng)過(guò)斷點(diǎn)發(fā)現(xiàn)喇伯,這個(gè)方法是執(zhí)行了,indexPath也是正確傳遞了上一次被選中cell的位置拨与。但是在didDeselect方法中使用
collectionView.cellForItem(at: indexPath)
得到的結(jié)果是nil稻据。出現(xiàn)不知道的問(wèn)題了怎么辦?看文檔买喧。
cellForItem(at:)
的官方說(shuō)明是 "Returns the visible cell object at the specified index path."好吧捻悯,我承認(rèn)我的基礎(chǔ)知識(shí)很爛。我是個(gè)智障淤毛。今缚。。
因?yàn)榧弦晥D會(huì)創(chuàng)建最大可見(jiàn)cell數(shù) maxVisibled+1個(gè)cell低淡,滑動(dòng)中姓言,超出這個(gè)范圍的cell會(huì)被放進(jìn)緩沖區(qū)瞬项,即將出現(xiàn)的第maxVisibled+2個(gè)cell才會(huì)調(diào)用
cellForItemAt indexPath:
方法獲取,可能從緩沖池取何荚,可能重新創(chuàng)建(緩沖池里沒(méi)有可復(fù)用的cell時(shí))囱淋。但是本例中 [1, 0] 和 [0, 3] 這兩個(gè)位置的cell很尷尬,因?yàn)樗鼈冇肋h(yuǎn)不會(huì)被放進(jìn)緩沖區(qū)餐塘,不會(huì)被重新獲取妥衣,狀態(tài)就不會(huì)被重置。cellForItem(at: indexPath)
又無(wú)法取到不可見(jiàn)的cell戒傻,所以它們一旦被選中就無(wú)法取消了(除非在本頁(yè)中再次選中它税手,再在本頁(yè)中選中其他cell)。解決辦法也很簡(jiǎn)單需纳,增加一個(gè)變量持有被選中的cell來(lái)維護(hù)是否選中狀態(tài)就行了芦倒。不說(shuō)了,我看文檔去了候齿。熙暴。。
好吧慌盯,我又回來(lái)了周霉。。亚皂。
我發(fā)現(xiàn)壓根不用這么麻煩俱箱。。直接重寫UICollectionViewCell的 isSelected 屬性的didSet方法灭必,在這個(gè)方法里更換圖片就行了狞谱。。禁漓。因?yàn)檫@里的UICollectionView的allowsMultipleSelection是false跟衅,并不允許多選,所以選擇其他cell時(shí)播歼,會(huì)自動(dòng)取消上一個(gè)被選中cell的選中狀態(tài)伶跷。。秘狞。