首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >如何在自定义布局集合视图中取消选择不可见的单元格?

如何在自定义布局集合视图中取消选择不可见的单元格?
EN

Stack Overflow用户
提问于 2017-11-17 14:56:29
回答 1查看 384关注 0票数 1

即使索引位置不为空,获取不可见单元格也可能得到该单元格,也可能得不到该单元格。

摘要:我尝试过在shouldSelectItemAt函数中选择和取消选择逻辑。选择进行得很顺利。但是在选择新的单元格时,需要取消选择先前选择的单元格。当我使用自定义集合视图布局时,我怀疑这个问题是由于单元格的可重用性造成的。

代码:

代码语言:javascript
复制
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
}

注意:我正在使用CustomUICollectionViewFlowLayout,我只需要使用shouldSelectItemAt函数。没有用于选择和取消选择的其他函数。

EN

回答 1

Stack Overflow用户

发布于 2017-11-17 15:37:55

代码语言:javascript
复制
let prevCell = try collectionView.cellForItem(at: previouslySelectedIndex) as? MyCollectionViewController.MyContentCell 

返回nil,因为如果用户滚动的collectionView单元格可能已被其他indexPath重用,则返回nil。

因此您不应该从collectionView中请求单元格,而应该请求数据源

代码语言:javascript
复制
let cell = self.collectionView?.dataSource?.collectionView(self.collectionView!, cellForItemAt: IndexPath(row: 0, section: 0))

另一种方法是在重用单元之前使用prepareForReuse重置单元状态。不过,对我来说,prepareForReuse听起来更合理:)

编辑:

再想一想,虽然上面的代码将返回单元格,但更新未加载/重用的单元格的UI将导致负面影响。相反,您可以在shouldSelectItemAt中仅在单元格可用时更新取消选择的单元格的UI

代码语言:javascript
复制
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
        }
    }

如果上面添加的let应该注意确保您更新单元格的UI,以便仅当它可用时才取消选择它。

现在在单元中实现prepareForReuse

代码语言:javascript
复制
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

代码语言:javascript
复制
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
 }

希望这能有所帮助

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/47344946

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档