Звучит так, будто вы этого хотите:
Вы не сказали, как помещаете синий кружок в клетку.Вот как я думаю, что вы должны обрабатывать выделение: максимально используйте встроенную поддержку выделения в представлении коллекции.
A UICollectionView
уже имеет поддержку выбора ячеек.По умолчанию его свойство allowsSelection
имеет значение true, а свойство allowsMultipleSelection
- false, поэтому он позволяет пользователю выбирать один элемент за раз, касаясь элемента.Это звучит почти как то, что вы хотите.
Представление коллекции делает текущий выбор доступным в своем свойстве indexPathsForSelectedItems
, которое либо равно нулю, либо пусто, когда ячейка не выбрана, и содержит ровно один путь индекса, когдаэлемент выбран.
Когда элемент выбран, и для элемента есть видимая ячейка, ячейка показывает, что ее элемент выбран, делая видимым 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
имеет значение false.Один из способов включить повторное нажатие - отменить 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
}
}