didDeselectItemAt当选择另一个单元格时,不会触发indexPath

时间:2017-07-28 12:07:31

标签: ios swift uicollectionview

我正在尝试实现此功能:在我的应用中,如果我在UICollectionView中选择了一个单元格,则边框变为蓝色,如果我选择另一个,则应取消选择前一个并且边框应变为透明。我写过一些方法:

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ChatCell

        /* Set some settings */
        if globalSelected[indexPath.item] {
            cell.circleView.layer.borderColor = UIColor.blue.cgColor
        } else {
            cell.circleView.layer.borderColor = UIColor.clear.cgColor
        }

        return cell
}

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    //Global variable for maintain selection
    global.selectedChatPath = indexPath
    globalSelected[indexPath.item] = true
    collectionView.reloadData()
}

func collectionView(_ collectionView: UICollectionView, didDeselectItemAt indexPath: IndexPath) {
    if indexPath != nilPath {
        globalSelected[indexPath.item] = false
        collectionView.reloadData()
    }
}

nilPath 只是 IndexPath(item:-1,section:0) ,但它没有没关系,因为甚至没有调用 collectionView(_ collectionView:UICollectionView,didDeselectItemAt indexPath:IndexPath) 。我的CollectionView具有 allowSelection = true allowsMultipleSelection = false 属性。我会感谢任何帮助。

5 个答案:

答案 0 :(得分:3)

如果同时只选择一个单元格我建议将当前选择的索引路径放入实例变量(nil表示没有选择任何内容)

var selectedIndexPath : IndexPath?

cellForItemAt中根据实例变量设置颜色

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ChatCell

    /* Set some settings */
    if let selected = selectedIndexPath, selected == indexPath {
        cell.circleView.layer.borderColor = UIColor.blue.cgColor
    } else {
        cell.circleView.layer.borderColor = UIColor.clear.cgColor
    }

    return cell
}

didSelectItemAt中仅重新加载上一个和新选择的单元格,并将selectedIndexPath设置为新选择的索引路径。这比重新加载整个集合视图更有效。

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    //Global variable for maintain selection

    var cellsToReload = [indexPath]
    if let selected = selectedIndexPath {
        cellsToReload.append(selected)
    }
    selectedIndexPath = indexPath
    collectionView.reloadItems(at: cellsToReload)
}
仅当您要明确取消选择单元格时才需要

didDeselectItemAt

答案 1 :(得分:1)

试试这个

    func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
        let cell = collectionView.dequeueReusableCell(withReuseIdentifier: reuseIdentifier, for: indexPath) as! ChatCell

        /* Set some settings */
        if globalSelected[indexPath.item] {
            cell.circleView.layer.borderColor = UIColor.blue.cgColor
            collectionView.selectItemAtIndexPath(indexPath, animated: false, scrollPosition: .None)
        } 
        else {
            cell.circleView.layer.borderColor = UIColor.clear.cgColor
            collectionView.deselectItemAtIndexPath(indexPath, animated: false)
        }
        return cell
       }

答案 2 :(得分:0)

func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
    let cell = collectionView.dequeueReusableCell(withReuseIdentifier: cellIdentifier, for: indexPath) as! CollectionViewCell
  if selectedIndex == indexPath.item {
    cell.backgroundColor = .blue
  } else {
    cell.backgroundColor = .clear
  }
}

和didSelectItemAt,

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
  selectedIndex = indexPath.item
  collectionView.reloadData()
}

答案 3 :(得分:0)

每次选择单元格时重新加载UICollectionView,然后更改所需单元格的边框。 当您重新加载数据时,前一个单元格的边框将被删除,之后您可以将边框添加到所需的单元格。

答案 4 :(得分:0)

didDeselectItem在您再次点击所选单元格之前不会被调用。要在点击其他单元格时取消选择先前选定的单元格,您需要将全局变量中先前选定的单元格设置设置为false中的didSelectItem,如下所示:

func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    globalSelected[global.selectedChatPath.item] = false //Set the previously selected cell's setting to false

    //Global variable for maintain selection
    global.selectedChatPath = indexPath
    globalSelected[indexPath.item] = true
    collectionView.reloadData()
}