如何突出显示选定的 UICollectionView 单元格? (Swift)

How can I highlight selected UICollectionView cells? (Swift)

我有一个 UICollectionView,用户可以 select 多个单元格。跟踪哪些单元格已被 select 编辑有点困难,因此我需要一些方法来在单元格被点击时设置 highlighting/creating 边框。

代码:

func collectionView(collectionView: UICollectionView, shouldSelectItemAtIndexPath indexPath: NSIndexPath) -> Bool {

    addToList.append(objectsArray[indexPath.row])

    return true

}

使用

collectionView.reloadItemsAtIndexPaths([indexPath])

重新加载当前单元格,或

collectionView.reloadData()

重新加载 shouldSelectItemAtIndexPath

中的所有单元格

然后在 cellForItemAtIndexPath 中设置边框或背景颜色(如果单元格被标记为已选中)(您可能需要一个新数组用于已选中的单元格,最好使用 indexPaths。

您可以像下面的代码一样在 didSelectItemAtIndexPath 覆盖事件上使用边框更改,并在单元格上分配新设置。

Swift 3.x:

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    addToList.append(objectsArray[indexPath.row])
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.layer.borderWidth = 2.0
    cell?.layer.borderColor = UIColor.gray.cgColor
}

这是我的解决方案,我确信它有效。

我的解决方案包括 3 种高光效果,UICollectionCellselectedBackgroundViewcell.contentView.backgroundColor 或您自己的 specialHighlightedArea;随意选择您需要的效果,并根据您的 App Designer 的要求随意添加更多效果。

如何使用?就继承BaseCollectionViewCell。如果需要,在单元格的 initcollectionView 的委托方法中进行配置。

如果你不需要高亮效果,找一个名为'shouldHighlightItemAtIndexPath' in UICollectionViewDelegate和return false的方法或者直接设置cell.shouldTintBackgroundWhenSelected = false.

extension UIColor {
    convenience init(rgb: Int, alpha: CGFloat = 1.0) {
        self.init(red: CGFloat((rgb & 0xFF0000) >> 16) / 255.0, green: CGFloat((rgb & 0xFF00) >> 8) / 255.0, blue: CGFloat(rgb & 0xFF) / 255.0, alpha: alpha)
    }
}
/// same with UITableViewCell's selected backgroundColor
private let cellHighlightedColor = UIColor(rgb: 0xD8D8D8) 

class BaseCollectionViewCell: UICollectionViewCell {

    var shouldTintBackgroundWhenSelected = true // You can change default value
    var specialHighlightedArea: UIView?

    // make lightgray background show immediately(on touch)
    // (使灰背景在手指触到 cell 时立即出现)
    override var isHighlighted: Bool { 
        willSet {
            onSelected(newValue)
        }
    }
    // keep lightGray background from selected until unselected 
    // (保留灰背景直至取消选中)
    override var isSelected: Bool { 
        willSet {
            onSelected(newValue)
        }
    }
    func onSelected(_ newValue: Bool) {
        // selectedBackgroundView is defined by UICollectionViewCell
        guard selectedBackgroundView == nil else { return }
        if shouldTintBackgroundWhenSelected {
            contentView.backgroundColor = newValue ? cellHighlightedColor : UIColor.clear
        }
        if let sa = specialHighlightedArea {
            sa.backgroundColor = newValue ? UIColor.black.withAlphaComponent(0.4) : UIColor.clear
        }
    }
}

尝试使边框足够粗以覆盖整个单元格

代码:

override func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
    addToList.append(objectsArray[indexPath.row])
    let cell = collectionView.cellForItem(at: indexPath)
    cell?.layer.borderWidth = 200.0
    cell?.layer.borderColor = UIColor.init(red: 0/255, green: 0/255, blue: 0/255, alpha: 0.4).cgColor
}

您可以创建自定义的 collcetionViewCell,并覆盖:

class MyCell: UICollectionViewCell {

    override var isHighlighted: Bool {
        didSet {
            if self.isHighlighted {
                print("yes")
                // Your customized animation or add a overlay view
            } else {
                print("no")
                // Your customized animation or remove overlay view
            }
        }
    }
}

通过这种方式,您可以创建类似 UITableViewCell 高亮效果的结果。

没有子类化:

如果您不想创建自己的 collectionViewCell。您可以使用委托方法:

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

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

你可以用它做同样的事情。

多选单元格,可以按如下方式进行:

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

    if let currentCell = collectionView.cellForItem(at: indexPath) as? QuestionnaireCollectionViewCell {

        // Your selection logic, you can change it according to your requirement
       if currentCell.selectedImage.isHidden == true{
           currentCell.selectedImage.isHidden = false

       }
       else{
          currentCell.selectedImage.isHidden = true
       }
    }

    }

}

对于单选,您可以在您的 collectionviewcell class 中使用 isSelected,如下所示:

 override var isSelected: Bool{
   didSet{
     if self.isSelected
     {
     //This block will be executed whenever the cell’s   selection state is set to true (i.e For the selected cell)
     }
    else
     {
     //This block will be executed whenever the cell’s selection state is set to false (i.e For the rest of the cells)
     }
   }
}

SWIFT

将此代码添加到您的 UICollectionViewCell 子类中:

 override var isSelected: Bool {
    didSet{
        if self.isSelected {
            UIView.animate(withDuration: 0.3) { // for animation effect
                 self.backgroundColor = UIColor(red: 115/255, green: 190/255, blue: 170/255, alpha: 1.0)
            }
        }
        else {
            UIView.animate(withDuration: 0.3) { // for animation effect
                 self.backgroundColor = UIColor(red: 60/255, green: 63/255, blue: 73/255, alpha: 1.0)
            }
        }
    }
}

这将设置单个选定单元格的颜色,并从任何先前选定的单元格中删除选定颜色。我给它添加了一个流畅的动画。我觉得挺好的,不过是可选的。

尝试使用此代码突出显示集合视图单元格

func collectionView(_ collectionView: UICollectionView, didHighlightItemAt indexPath: IndexPath) {
    if let cell = collectionView.cellForItem(at: indexPath) {
        cell.contentView.backgroundColor = #colorLiteral(red: 1, green: 0.4932718873, blue: 0.4739984274, alpha: 1)
    }
}

func collectionView(_ collectionView: UICollectionView, didUnhighlightItemAt indexPath: IndexPath) {
    if let cell = collectionView.cellForItem(at: indexPath) {
        cell.contentView.backgroundColor = nil
    }
}

使用三元运算符

  override var isSelected: Bool {
        didSet {
                        UIView.animate(withDuration: 0.3) {
                            self.backgroundColor = self.isSelected ? .systemGray4 : .systemGray6
                        }
                    }
                }