将 UICollectionView 的某些部分的触摸传递给底层视图

Pass touches on some part of UICollectionView to underlying views

先看看附件图:

我的层次结构如下所示:

UICollectionView 作为 H:[collectionView(==270)]|V:|-(70)-[collectionView]-(70)-| 添加到 UIVew。

我有两个要求:

1) 只有 UICollectionViewCell 的蓝色部分应该触发 collectionView::didSelectItemAtIndexPath: 方法。我已经用

成功地实现了
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];
    if (hitView == self.customView) {
        return self;
    }
    return nil;
}

自定义 class UIColectionViewCell。 customView 属性 是单元格的 blue/red UIView。 这按预期工作。

2) 我希望在 UICollectionViewCell 的绿色部分或 UICollectionVIew 本身(这里的背景为白色,不透明度为 0.5)中完成的任何手势(Tap/LongTap/Pan/...)传递给超级视图。例如下面的绿松石色 UIButtion。 绿色部分也不应滚动 CollectionView .. 它必须对任何手势完全透明。

我该怎么做?尝试了很多不同的方法,但其中 none 有效。我知道如何使用常规 UIView 执行此操作,但无法让它在 UICollectionView 及其单元格上工作。

请记住,还有其他可交互的 UIView 或 UIButtion,它们位于集合视图的绿色部分下方。绿色稍后将只是 UIClearColor。

只让 UICollectionView 的宽度更小(蓝色部分的宽度)的建议不是一个选项,因为在某些情况下,UICell 的 Blue/Red 部分必须延伸到单元格的整个宽度。

以上示例的最终解决方案如下:

1) 仅需要 red/blue 部分可点击。 这基本保持不变。我参考了 blue/red UIView 名称 customView

- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];
    if (hitView == self.customView) {
        return self;
    }
    return nil;
}

2) 应忽略未在 blue/red UIView 上完成的 UICollectionView 内的任何交互。

继承 UICollectionView 并添加覆盖此方法:

- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event {

    NSIndexPath *indexPath = [self indexPathForItemAtPoint:point];
    LCollectionViewCell *cell = (LCollectionViewCell*)[self cellForItemAtIndexPath:indexPath];

    if (cell && [self convertPoint:point toView:cell.customView].x >= 0) {
        return YES;
    }
    return NO;
}

这将检查 CGPoint 是否在 customView 上完成。有了这个,我们还支持可变宽度:

您的回答对我帮助很大,谢谢!

这是 Swift 3.0 中的解决方案:

 override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView? {
    let hitView = super.hitTest(point, with: event)
    if hitView == self.customView {
        return self
    }
    return nil
}