我最近一直在使用UICollectionView。有一个需要实现的要求,例如:“几个collectionview单元中有多个imageview。当用户选择一个图像/单元时,该应用将在该图像/单元周围绘制一个蓝色圆圈。” 目前,我可以在单元上进行抽奖了。但是现在的问题是我一次只能绘制所有单元格,而不能绘制一个单元格(如下图所示)
所以我的问题是:如何选择一个图像/单元格,应该删除上一个选定单元格的蓝色圆圈?
非常感谢您预先提供答案。
答案 0 :(得分:0)
听起来像您想要这样:
您没有说出如何将蓝色圆圈放入单元格中。我认为这是您应该进行选择的方式:尽可能使用集合视图的内置选择支持。
UICollectionView
已支持选择单元格。默认情况下,其allowsSelection
属性为true,而其allowsMultipleSelection
属性为false,因此它允许用户通过点击项目一次选择一个项目。听起来几乎就是您想要的。
集合视图在其indexPathsForSelectedItems
属性中提供当前选择,当未选择任何单元格时该属性为nil或为空,并且在选择一项时仅包含一个索引路径。
当一个项目被选中,并且该项目有一个可见的单元格时,该单元格通过使其selectedBackgroundView
可见来显示该项目已被选中。因此,创建一个显示蓝色圆圈的UIView
子类:
class CircleView: UIView {
override class var layerClass: AnyClass { return CAShapeLayer.self }
override func layoutSubviews() {
super.layoutSubviews()
let layer = self.layer as! CAShapeLayer
layer.strokeColor = UIColor.blue.cgColor
layer.fillColor = nil
let width: CGFloat = 3
layer.lineWidth = width
layer.path = CGPath(ellipseIn: bounds.insetBy(dx: width / 2, dy: width / 2), transform: nil)
}
}
然后使用CircleView
的实例作为单元格的selectedBackgroundView
。您可以在第一次选择该单元格时延迟创建实例:
class MyCell: UICollectionViewCell {
override var isSelected: Bool {
willSet {
if newValue && selectedBackgroundView == nil {
selectedBackgroundView = CircleView()
}
}
}
var title: String = "???" {
didSet {
label.text = title
}
}
@IBOutlet private var label: UILabel!
}
使用此代码后,用户可以点击一个单元格以选择其项目,并且选中该单元格时将显示一个蓝色圆圈。轻按另一个单元格将取消选择先前选择的项目,蓝色圆圈将“移动”到新选择的项目的单元格。
您可能想让用户通过再次点按来取消选择所选项目。如果UICollectionView
为假,默认情况下allowsMultipleSelection
不会这样做。启用重新点击选择的一种方法是在collectionView(_:shouldSelectItemAt:)
中实现UICollectionViewDelegate
:
override func collectionView(_ collectionView: UICollectionView, shouldSelectItemAt indexPath: IndexPath) -> Bool {
if (collectionView.indexPathsForSelectedItems ?? []).contains(indexPath) {
// Item is already selected, so deselect it.
collectionView.deselectItem(at: indexPath, animated: false)
return false
} else {
return true
}
}