获取不可见的单元格可能会也可能不会获取单元格,即使索引位置不为空。
总结:我已经尝试在shouldSelectItemAt函数中选择和取消选择逻辑。选择顺利。但是在选择新单元时,需要取消选择先前选择的单元。当我使用自定义集合视图布局时,我怀疑由于单元格的可重用性而出现问题。
代码:
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
if(collectionView == customContentCollectionView){
let cell:MyContentCell = collectionView.cellForItem(at: indexPath)! as! MyCollectionViewController.MyContentCell
// DESELECTION CODE
if(previouslySelectedIndex != nil){
// following line is error prone (executes but may or may not fetch the cell, sometimes deselect sometimes doesnt)
let prevCell = try collectionView.cellForItem(at: previouslySelectedIndex) as? MyCollectionViewController.MyContentCell
// Also tried with this following (executes but fails sometimes, in case not fetching the cell)
//let prevCell = try collectionView.cellForItem(at: previouslySelectedIndex)! as! MyCollectionViewController.MyContentCell
// Tried this one as well, fetching the previously selected cell using datasource, not directly from collection view
// let prevCell = customContentCollectionView.dataSource?.collectionView(collectionView, cellForItemAt: previouslySelectedIndex) as? MyCollectionViewController.MyContentCell
prevCell?.shapeLayer.strokeColor = bubbleBorder.cgColor
prevCell?.shapeLayer.fillColor = bubbleFill.cgColor
prevCell?.shapeLayer.shadowOpacity = 0.0
prevCell?.labelCount.textColor = bubbleBorder
}
// SELECTION CODE HERE GOES PRETTY WELL
...
previouslySelectedIndex = indexPath
}
N.B。 :我正在使用CustomUICollectionViewFlowLayout,我只需要使用shouldSelectItemAt函数。没有其他功能可供选择和取消选择。
答案 0 :(得分:0)
let prevCell = try collectionView.cellForItem(at: previouslySelectedIndex) as? MyCollectionViewController.MyContentCell
返回nil,因为如果用户滚动了collectionView单元格可能已经被重用于其他一些indexPath,那么返回nil。
所以你不应该要求来自collectionView
的单元格,而应该询问数据源
let cell = self.collectionView?.dataSource?.collectionView(self.collectionView!, cellForItemAt: IndexPath(row: 0, section: 0))
其他方法是在重用之前使用prepareForReuse
重置单元状态。 prepareForReuse
听起来更合理的解决方案:)
修改强>
第二个想法虽然上面的代码将返回单元格,更新未加载/重用的单元格的UI将导致不利影响。相反,只有当单元格可用时,您才可以在shouldSelectItemAt
更新取消选择的单元格的UI
func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
if(collectionView == customContentCollectionView){
let cell:MyContentCell = collectionView.cellForItem(at: indexPath)! as! MyCollectionViewController.MyContentCell
// DESELECTION CODE
if(previouslySelectedIndex != nil){
// following line is error prone (executes but may or may not fetch the cell, sometimes deselect sometimes doesnt)
if let prevCell = try collectionView.cellForItem(at: previouslySelectedIndex) as? MyCollectionViewController.MyContentCell {
// Also tried with this following (executes but fails sometimes, in case not fetching the cell)
//let prevCell = try collectionView.cellForItem(at: previouslySelectedIndex)! as! MyCollectionViewController.MyContentCell
// Tried this one as well, fetching the previously selected cell using datasource, not directly from collection view
// let prevCell = customContentCollectionView.dataSource?.collectionView(collectionView, cellForItemAt: previouslySelectedIndex) as? MyCollectionViewController.MyContentCell
prevCell?.shapeLayer.strokeColor = bubbleBorder.cgColor
prevCell?.shapeLayer.fillColor = bubbleFill.cgColor
prevCell?.shapeLayer.shadowOpacity = 0.0
prevCell?.labelCount.textColor = bubbleBorder
}
}
// SELECTION CODE HERE GOES PRETTY WELL
previouslySelectedIndex = indexPath
}
}
如果在上面添加,则应注意确保更新单元格的UI,以便仅在可用时才取消选择。
现在在单元格中实现prepareForReuse
override func prepareForReuse() {
//reset all the fields of cell
self.shapeLayer.strokeColor = bubbleBorder.cgColor
self.shapeLayer.fillColor = bubbleFill.cgColor
self.shapeLayer.shadowOpacity = 0.0
self.labelCount.textColor = bubbleBorder
}
最后在cellForItemAtIndexPath
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
//your code to create cell n all
if(indexPath == previouslySelectedIndex) {
//your code to select the cell
}
return cell
}
希望这有帮助