如何突出显示选定的 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 种高光效果,UICollectionCell
的 selectedBackgroundView
、cell.contentView.backgroundColor
或您自己的 specialHighlightedArea
;随意选择您需要的效果,并根据您的 App Designer 的要求随意添加更多效果。
如何使用?就继承BaseCollectionViewCell
。如果需要,在单元格的 init
或 collectionView
的委托方法中进行配置。
如果你不需要高亮效果,找一个名为'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
}
}
}
我有一个 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 种高光效果,UICollectionCell
的 selectedBackgroundView
、cell.contentView.backgroundColor
或您自己的 specialHighlightedArea
;随意选择您需要的效果,并根据您的 App Designer 的要求随意添加更多效果。
如何使用?就继承BaseCollectionViewCell
。如果需要,在单元格的 init
或 collectionView
的委托方法中进行配置。
如果你不需要高亮效果,找一个名为'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
}
}
}