我可以让一些 CollectionView 部分是单选的,而其他的是多选的吗?

Can I have some CollectionView sections be single selection and others be multiple selection?

我的某些 CollectionView 部分应该只允许用户 select 单个选项,而其他部分应该允许用户在该部分中选择任意数量。我如何设计一个 CollectionView,使得某些部分允许多个 selection 而其他部分仅允许单个 selection?

我正在构建一个送餐应用程序,它要求用户 select 从选项屏幕中自定义他们的订单(即选择糖度或选择配菜)。我目前将可自定义选项列表显示为一个 UICollectionView,其中不同的部分指定了他们想要自定义的内容。为澄清起见,header 部分可能会显示 "Choose your Drink" 并且该部分中的单元格会列出 "Coke," "Pepsi," 等

class MenuDetailVC: UIViewController, UICollectionViewDelegate, UICollectionViewDataSource, UICollectionViewDelegateFlowLayout {

    var item: MenuItem?
    var cvCellID = "collectionviewid"
    var masterCustomizables: [MasterCustomize]?

    override func viewDidLoad() {
        super.viewDidLoad()
        masterCustomizables = item?.customizables
        setupCV()
    }
//...

    func setupCV() {
        masterCollectionView.dataSource = self
        masterCollectionView.delegate = self
        masterCollectionView.register(CustomizeCellHeader.self, forSupplementaryViewOfKind: UICollectionView.elementKindSectionHeader, withReuseIdentifier: "headerID")
        masterCollectionView.register(CustomizeCell.self, forCellWithReuseIdentifier: cvCellID)
        masterCollectionView.backgroundColor = UIColor.white
        masterCollectionView.allowsMultipleSelection = true
    }
}

extension MenuDetailVC {
    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cvCellID, for: indexPath) as! CustomizeCell
        cell.customizable = masterCustomizables?[indexPath.section].choices?[indexPath.row]
        return cell
    }

    func numberOfSections(in collectionView: UICollectionView) -> Int {
        if let count = masterCustomizables?.count {
            return count
        } else {
            return 0
        }
    }

    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        if let count = masterCustomizables?[section].choices?.count {
            return count
        } else {
            return 0
        }
    }

class MasterCustomize 有一个实例变量 .isRequired,它是 returns 一个 bool,如果 .isRequired == true,该部分应该包含单个 selection 单元格。否则,它应该包含多个 selection 单元格。显然,程序的当前状态只有 returns 个 select 离子细胞。谢谢!

collectionView shouldSelectItemAt 方法中检查 .isRequired 值。如果为真,请检查该部分中所选单元格的数量。如果现有的选定单元格计数为 0,则 return 为真。

如果.isRequired值为false,return true

func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
    if (masterCustomizables ?? [])[indexPath.section].isRequired {
        return collectionView.indexPathsForSelectedItems?.filter { [=10=].section == indexPath.section }.count == 0
    } else {
        return true
    }
}

更新

如果 isRequired 为真,以编程方式取消选择已选择的单元格。

func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
    if (masterCustomizables ?? [])[indexPath.section].isRequired,
        let existingSelectedIndex = collectionView.indexPathsForSelectedItems?.first(where: { [=11=].section == indexPath.section }) {
            collectionView.deselectItem(at: existingSelectedIndex, animated: true)
    }
    return true
}