Понимание Моджтабы Хоссейни очень умно, но данный ответ может быть не совсем правильным.
Оказывается, на главном экране есть UITapGestureRecognizer; если он распознает до нажатия на ячейку, он предотвращает выбор ячейки. Но если вы просто установите cancelsTouchesInView
в false
на этом распознавателе жестов, то они оба будут работать, и это вряд ли будет тем, что нужно. Мы обязательно хотим, чтобы касание ячейки, а не касание распознавателя жестов касания.
Таким образом, правильное решение состоит в том, чтобы дать распознавателю жестов касания делегата и реализовать gestureRecognizerShouldBegin
. Здесь мы смотрим, чтобы увидеть , где кран. Если оно находится в пределах ячейки, мы возвращаем false
; в противном случае мы возвращаем true
. Таким образом, мы являемся посредником между касанием ячейки и касанием распознавателя жестов.
Вот возможная реализация, продемонстрированная в очень упрощенной форме:
extension UIView {
func isDescendant(of whattype:UIView.Type) -> Bool {
var sup : UIView? = self.superview
while sup != nil {
if (whattype == type(of:sup!)) {
return true
}
sup = sup!.superview
}
return false
}
}
class ViewController: UIViewController, UICollectionViewDataSource, UICollectionViewDelegate, UIGestureRecognizerDelegate {
override func viewDidLoad() {
super.viewDidLoad()
let t = UITapGestureRecognizer(target: self, action: #selector(tap))
self.view.addGestureRecognizer(t)
t.delegate = self
}
@objc func tap(_:UIGestureRecognizer) {
print("tap")
}
func collectionView(_ collectionView: UICollectionView, numberOfItemsInSection section: Int) -> Int {
return 1
}
func collectionView(_ collectionView: UICollectionView, cellForItemAt indexPath: IndexPath) -> UICollectionViewCell {
let cell = collectionView.dequeueReusableCell(withReuseIdentifier: "cell", for: indexPath)
return cell
}
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("select")
}
func gestureRecognizerShouldBegin(_ gr: UIGestureRecognizer) -> Bool {
if let v = gr.view {
let loc = gr.location(in: v)
if let v2 = v.hitTest(loc, with: nil) {
return !v2.isDescendant(of: UICollectionViewCell.self)
}
}
return true
}
}
Как видите, мы смотрим, находится ли кран внутри ячейки представления коллекции; если это так, наш распознаватель жестов не сможет распознать, и выбор будет выполнен немедленно.