【问题标题】:Get the selected cells count in UICollectionView获取 UICollectionView 中选定的单元格计数
【发布时间】:2021-06-29 07:33:27
【问题描述】:

如何从 UICollectionView 中获取选定的单元格计数和选定的单元格数组,我需要设置选择的限制。下面是我的代码,它不起作用。请指导。谢谢

 func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
    let indexPaths = collectionView.indexPathsForSelectedItems!
        print(indexPaths)
    if let selectedItems = collectionView.indexPathsForSelectedItems {
                if selectedItems.count >= 3 {
                    collectionView.deselectItem(at: indexPath as IndexPath, animated: true)
                    return false
                }
            }
    return true
}

上面用 didSelect 方法编写的代码只返回选定的单元格索引,但这里只是跳到最后一行

return true 

【问题讨论】:

  • 您可以获取选定项目的索引路径,但无法获取选定单元格的数组,因为单元格是为了重复使用
  • @SPatel 我需要至少获得选定的单元格计数
  • 在 didSelect 上只是将它的索引路径存储在数组中(如果已经包含则删除它)
  • @SPateli 不这么认为。我们可以从 collection.indexPathsForSelectedItems 中获取计数
  • 您是否将allowsMultipleSelection 设置为true?

标签: ios swift iphone xcode uicollectionview


【解决方案1】:

您可以使用UICollectionViewDelegate 中的shouldSelectItemAt 委托方法来实现:

func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
    return collectionView.indexPathsForSelectedItems?.count ?? 0 <=  selectionLimit
}

演示其工作原理的示例演示:

class ViewController : UIViewController {
    private var myCollectionView:UICollectionView?
    private var selectionLimit = 4

    override func viewDidLoad() {
        super.viewDidLoad()

        let view = UIView()
        view.backgroundColor = .white

        let layout: UICollectionViewFlowLayout = UICollectionViewFlowLayout()
        layout.sectionInset = UIEdgeInsets(top: 20, left: 10, bottom: 10, right: 10)
        layout.itemSize = CGSize(width: UIScreen.main.bounds.width * 0.7, height: 60)

        myCollectionView = UICollectionView(frame: self.view.frame, collectionViewLayout: layout)
        myCollectionView?.register(UICollectionViewCell.self, forCellWithReuseIdentifier: "MyCell")
        myCollectionView?.backgroundColor = UIColor.white

        myCollectionView?.allowsMultipleSelection = true
        myCollectionView?.dataSource = self
        myCollectionView?.delegate = self

        view.addSubview(myCollectionView ?? UICollectionView())

        self.view = view
    }
}
extension ViewController: UICollectionViewDataSource {
    func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
        return 20
    }

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let myCell = collectionView.dequeueReusableCell(withReuseIdentifier: "MyCell", for: indexPath)
        myCell.backgroundColor = UIColor.blue
        return myCell
    }
}
extension ViewController: UICollectionViewDelegate {

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("Did select a cell at \(indexPath.row)")
        let itemsLeftToSelect = selectionLimit - (collectionView.indexPathsForSelectedItems?.count ?? 0)
        print("Have \(itemsLeftToSelect) items to select")
    }

    func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
        print("Did deselect a cell at \(indexPath.row)")
        let itemsLeftToSelect = selectionLimit - (collectionView.indexPathsForSelectedItems?.count ?? 0)
        print("Have \(itemsLeftToSelect) items to select")
    }

    func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
        return collectionView.indexPathsForSelectedItems?.count ?? 0 <  selectionLimit
    }
}

当你达到选择限制时,shouldSelectItemAt 将返回 false,didSelectItemAt 函数将不再被调用。另一方面,如果您单击已选择的单元格,didDeselectItemAt 将被调用,您将被调用,您可以再次选择 + 1 个单元格,因为所选项目的数量将减少 1。另请参阅示例中的调试日志。

【讨论】:

  • 不工作,只是打印所选单元格的索引
  • @iPhone7 很可能您的indexPathsForSelectedItems 数组返回1,因为您将allowsMultipleSelection 设置为false。尝试将其设置为true,它会工作
  • 如果是这样,我不应该被允许选择多个单元格,但我可以
  • @iPhone7 查看我的更新。我提供了一个示例供您测试。
  • 很抱歉,但也不起作用,didDeselect 永远不会被调用。即使取消选择单元格
【解决方案2】:

更好的方法是基于模型

在你的数据模型中添加一个属性

var isSelected = false

并在取消/选择单元格时相应地重新/设置它。

那么你就可以简单的统计选中的数据源项了——dataSource代表数据源数组

func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
    return dataSource.filter{$0.isSelected}.count < 3
}

此外,在此方法中无需取消选择行,因为您会阻止用户选择超过 2 行。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-02-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多