将tapGestureRecognizer添加到其backgroundview时无法触发collectionview的事件

Can not trigger the event of collectionview when add tapGestureRecognizer to its backgroundview

  1. 将集合视图添加到视图中将视图添加到视图中

  2. 背景视图(UIView)

  3. 将 tapGestureRecognizer 添加到 backgroundView

collectionview的select事件点击cell不触发,总是触发backgroundview的点击事件

let backgroundView = UIView(frame: sender.window!.bounds)
    backgroundView.backgroundColor = UIColor.yellowColor()

    let blueView = BlueView(frame: CGRect(x: 300, y: 200, width: 300, height: 400))
    backgroundView.addSubview(blueView)
    sender.window!.addSubview(backgroundView)
    backgroundView.userInteractionEnabled = true

    let gesture = UITapGestureRecognizer(target: blueView, action: "tapGestureRecognizer")
    gesture.delegate = blueView
    backgroundView.addGestureRecognizer(gesture)

........

    let cv = UICollectionView(frame: CGRect(x: 100, y: 0, width: 100, height: 340), collectionViewLayout: layout)
    cv.registerClass(UICollectionViewCell.self, forCellWithReuseIdentifier: "cell")
    cv.dataSource = self

    blueView.addSubview(cv)

谁知道原因?

我认为您已经回答了您的问题。

func collectionView(collectionView: UICollectionView, didSelectItemAtIndexPath indexPath: NSIndexPath)

它是来自 UICollectionView 的委托方法,因此当您在单元格内创建带有识别器的 UIView 时,它会接受触摸并且不会传递它们,因此集合视图不会调用它的委托方法。

如果你想要可能的解决方案,有很多:

1) 如果您只需要单元格内的自定义逻辑,当有人单击单元格时,您可以覆盖单元格内的 selected 并在此处添加您的逻辑:

class Cell: UICollectionViewCell {
    override var selected: Bool {
        didSet {

        }
    }
}

2) 您可以创建从点击识别器选择器或通知中调用的委托方法:

func tapGestureRecognizer() {
    NSNotificationCenter.defaultCenter().postNotificationName("TappedRecognizer", object: nil)
}

class YourController: UIViewController {

    override func viewDidLoad() {
        NSNotificationCenter.defaultCenter().addObserver(self, selector: "tappedRecognizer", name: "TappedRecognizer", object: nil)
    }

    func tappedRecognizer() {
        // your code here
    }
}

3) 我想它可以通过你的视图将你的触摸传递给单元格,所以它会调用 UICollectionView 的委托方法,那么你应该覆盖 UITapGestureRecognizerpointInside 方法,你可以搜索很多关于这个主题的代码,比如 this

问题是向 superview 添加 UIGestureRecognzer 也会影响其 subview 中的触摸事件。为避免这种情况,您需要实现 UIGestureRecognzer 的以下委托方法,并通过返回 false.

来否定 UIGestureRecogniser 的触摸操作
func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool
{
    var view = gestureRecognizer.view
    if view.tag != 100 //Set a tag for the backgroundview
    {
        return false
    }
    return true
}

编辑

查看您的代码,我怀疑您没有设置 UICollectionView 的委托。您刚刚设置了 DataSourcedidselect方法是委托方法,不是dataSource。尝试在您设置 UICollectionViewdataSource:

下方添加以下内容
cv.delegate= self