集合视图 - 如何在每个部分中仅选择一个单元格

Posted

技术标签:

【中文标题】集合视图 - 如何在每个部分中仅选择一个单元格【英文标题】:Collection View - How to select only one cell in each section 【发布时间】:2020-01-17 11:05:02 【问题描述】:

我的收藏视图有多个部分。我想要实现的是用户只能在每个部分中选择一个单元格(答案)。当单元格(答案)被选中时,背景颜色会改变。

我没有做的是示例:当用户单击第 1 节中的一个单元格时,我只想取消选择第 1 节中的另一个单元格。

下面是我的一些代码

    @IBOutlet var step3CollectionView: UICollectionView!

    var HexColor = HexColorClass()
    var dataPageThree : json_PageThree!    
    var step3AnswerArray : [Int] = []


    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 

        var frameCount = dataPageThree.step_instruction.first!.subquestions.count

        for i in 0..<frameCount

            if indexPath.section == i 
                step3AnswerArray[i] = (dataPageThree.step_instruction.first?.subquestions[i].subquestion_selection_answerNums![indexPath.row])!


            let callCell = self.step3CollectionView.cellForItem(at: indexPath) as? Step3CollectionViewCell

            callCell!.answerLabel.backgroundColor = HexColor.hexStringToUIColor(hex: "117577")

            callCell!.answerLabel.textColor = UIColor.white

            

        

    

 func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool 


        let indexPaths = collectionView.indexPathsForSelectedItems
        if (indexPaths?.count) ?? 0 > 0 

            /// If you need simple way
            for index in indexPaths! 
                if index.section == indexPath.section 
                    self.step3CollectionView.deselectItem(at: index, animated: true) // if want deselect previous selection

                    let callCell = self.step3CollectionView.cellForItem(at: index) as? Step3CollectionViewCell

                            callCell!.answerLabel.backgroundColor = UIColor.white

                            callCell!.answerLabel.textColor = UIColor.black
                    //return false  //if you do not want further selection
                
            


        

        return true
    

需要一些指导。

【问题讨论】:

可以发视频链接吗 【参考方案1】:

首先,将collectionView'sallowsMultipleSelection属性设置为true,即

override func viewDidLoad() 
    super.viewDidLoad()
    self.step3CollectionView.allowsMultipleSelection = true

现在,UICollectionViewDelegate 方法 collectionView(_: shouldSelectItemAt:) 应该是这样的,

func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool 
    collectionView.indexPathsForSelectedItems?.filter( $0.section == indexPath.section ).forEach( collectionView.deselectItem(at: $0, animated: false) )
    return true

另外,不要根据cell's 选择更改shouldSelectItemAtdidSelectItemAtcellbackgroundColour。 这使得代码变得庞大和冗余。

应该通过覆盖 isSelected 属性在 UICollectionViewCell 子类中完成。

class Step3CollectionViewCell: UICollectionViewCell         
    override var isSelected: Bool 
        didSet 
            self.answerLabel.backgroundColor = isSelected ? HexColor.hexStringToUIColor(hex: "117577") : .white
            self.answerLabel.textColor = isSelected ? .white : .black
        
    

有了上面的代码,也不需要在collectionView(_:didSelectItemAt:)方法中写color更改代码。用于选择和取消选择cell 的 UI 将被自动处理。

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) 
    step3AnswerArray[indexPath.section] = (dataPageThree.step_instruction.first?.subquestions[i].subquestion_selection_answerNums![indexPath.row])!

【讨论】:

以上是关于集合视图 - 如何在每个部分中仅选择一个单元格的主要内容,如果未能解决你的问题,请参考以下文章

如何根据集合视图中的单元格选择来控制表格视图的内容?

如何在选择 tableView 的行单元格(作为集合视图单元格)时显示视图控制器?

集合视图单元格重定向不同的 ViewController

如何将集合视图单元格滚动到可见区域的中间

如何在选择集合视图单元格时显示不同的视图控制器

呈现和关闭模式视图控制器时如何保持选择集合视图单元格?