将tapGestureRecognizer添加到其背景视图时无法触发collectionview的事件

Posted

技术标签:

【中文标题】将tapGestureRecognizer添加到其背景视图时无法触发collectionview的事件【英文标题】:Can not trigger the event of collectionview when add tapGestureRecognizer to its backgroundview 【发布时间】:2015-12-02 04:32:27 【问题描述】:

    将collectionview添加到view中添加view到a中

    背景视图(UIView)

    将 tapGestureRecognizer 添加到 backgroundView

collectionview的select事件不能在点击单元格时触发,总是触发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)

谁知道原因?

【问题讨论】:

如果我是对的,你添加到超级视图的手势也会影响子视图 【参考方案1】:

问题在于将UIGestureRecognzer 添加到superview 也会影响其subviews 中的触摸事件。为避免这种情况,您需要实现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 方法是委托方法,而不是数据源。尝试在您设置UICollectionViewdataSource下方添加以下内容:

cv.delegate= self

【讨论】:

你在哪里实现了委托方法? 我在包含gesture.delegate = self的类中实现了委托。它实际调用并在点击单元格时返回false,但它不会触发collection view的didselect事件【参考方案2】:

我认为你回答了你的问题。

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的委托方法,那么你应该为UITapGestureRecognizer覆盖pointInside方法,你可以搜索很多代码关于这个话题,比如this

【讨论】:

我没有在单元格内制作带有识别器的 UIView

以上是关于将tapGestureRecognizer添加到其背景视图时无法触发collectionview的事件的主要内容,如果未能解决你的问题,请参考以下文章

如何使用 c# 将 TapGestureRecognizer 添加到从 JSON 创建的项目中?

使用 xib 将 tapGestureRecognizer 添加到自定义 UIView

当我尝试将 TapGestureRecognizer 添加到我的 UIImageView 时出现此错误:Unrecognized selector sent to class

在 UIView 中将 tapGestureRecognizer 添加到 UIImageView 并通过协议调用方法

TapgestureRecognizer 将触摸检测为滚动视图

带有 TapGestureRecognizer 的最前面的 UIView 没有收到触摸