您好,我项目的特定viewController上有一个带有自定义类单元格的UICollectionView。但是我有一个很大的问题,那就是func:
func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
print("tapped on a cell")
}
在单元格上单击并立即释放(正常点击)时,它什么也不做,只是什么也没有。
如果我在不松开手指的情况下按住约1秒钟,它将变为灰色,突出显示
如果我按住至少3秒钟,则手指didSelectItemAt将正确执行。 我试图在另一个项目上做同样的事情,这很好,但在这个VC上却没有,我真的没有发现问题。 VC Bugged是Main.storyboard中的addTest类别
答案 0 :(得分:2)
在集合视图下可能有一个UIGesture
或其他可交互的事物。您应该禁用其在界面构建器中的cancel touches in view
功能:
或在代码中
myTapGestureRecognizer.cancelsTouchesInView = false
答案 1 :(得分:1)
Mojtaba Hosseini的见解非常聪明,但是给出的答案可能并不完全正确。
事实证明,主视图上有一个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
}
}
如您所见,我们将查看水龙头是否在集合视图单元格内;如果是,则会阻止我们的手势识别器进行识别,并且选择立即成功。