Представление коллекции - Как выбрать только одну ячейку в каждом разделе - PullRequest
0 голосов
/ 17 января 2020

Моя коллекция имеет несколько разделов. Я пытаюсь добиться того, чтобы пользователь мог выбрать только одну ячейку (ответ) в каждом разделе. Когда ячейка (ответ) выбрана, цвет фона изменится.

Что мне не удалось сделать, так это пример: когда пользователь щелкает ячейку в разделе 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 Ответ

1 голос
/ 17 января 2020

Прежде всего, установите для свойства collectionView's allowsMultipleSelection значение 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
}

Кроме того, не меняйте backgroundColour из cell в shouldSelectItemAt или didSelectItemAt в зависимости от выбора cell's. Это делает код громоздким и избыточным.

Это должно быть сделано в подклассе UICollectionViewCell путем переопределения свойства isSelected.

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

С помощью приведенного выше кода также нет необходимости писать код изменения color в методе collectionView(_:didSelectItemAt:). Пользовательский интерфейс для выбора и отмены cell будет обрабатываться автоматически.

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