collectionView didSlectRow错误

时间:2019-05-26 23:16:24

标签: swift xcode debugging uicollectionview

您好,我项目的特定viewController上有一个带有自定义类单元格的UICollectionView。但是我有一个很大的问题,那就是func:

    func collectionView(_ collectionView: UICollectionView, didSelectItemAt indexPath: IndexPath) {
        print("tapped on a cell")
    }

在单元格上单击并立即释放(正常点击)时,它什么也不做,只是什么也没有。

如果我在不松开手指的情况下按住约1秒钟,它将变为灰色,突出显示

如果我按住至少3秒钟,则手指didSelectItemAt将正确执行。 我试图在另一个项目上做同样的事情,这很好,但在这个VC上却没有,我真的没有发现问题。 VC Bugged是Main.storyboard中的addTest类别

2 个答案:

答案 0 :(得分:2)

在集合视图下可能有一个UIGesture或其他可交互的事物。您应该禁用其在界面构建器中的cancel touches in view功能:

Attributes inspector

或在代码中

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
    }
}

如您所见,我们将查看水龙头是否在集合视图单元格内;如果是,则会阻止我们的手势识别器进行识别,并且选择立即成功。