将UICollectionView的一些触摸事件传递给底层视图

4
首先看一下附图:enter image description here 我的层次结构如下所示:
- UIView - UIButton - UICollectionView - UICollectionViewCell - UICollectionViewCell - UICollectionViewCell - UICollectionViewCell
UICollectionView 被添加到 UIView 中,使用的约束为 H:[collectionView(==270)]|V:|-(70)-[collectionView]-(70)-|
我的两个需求是:
1. 只有 UICollectionViewCell 的蓝色部分应触发 collectionView::didSelectItemAtIndexPath: 方法。我已经成功实现了这一点。 2. 当 UICollectionViewCell 处于选定状态时,其它所有单元格的蓝色部分都应该显示。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
    UIView *hitView = [super hitTest:point withEvent:event];
    if (hitView == self.customView) {
        return self;
    }
    return nil;
}

关于自定义类UIColectionViewCell的问题。 customView 属性指的是 cell 的蓝色/红色 UIView。

这能够正常工作。

2) 我想将在 UICollectionViewCell 的绿色部分或 UICollectionVIew 本身(背景为白色,不透明度为0.5)执行的任何手势(Tap/LongTap/Pan/...)传递到父视图。例如下面的青色 UIButtion。 绿色部分也不应该滚动 CollectionView... 它必须对任何手势都完全透明。

我该如何做?尝试了很多不同的方法,但没有一个有效。我知道如何在普通UIView上实现它,但无法在UICollectionView及其单元格上实现它。

请记住,将有其他UIView或UIButtions被放置在集合视图的绿色部分下,并且可以进行交互。 绿色部分后来会变成UIClearColor。

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


1
为什么不能对UICollectionView进行子类化并覆盖hitTest方法? - beyowulf
谢谢。这很有用,让我坚定了继续走这条路的决心。之前我尝试过,但没有正确地对LCollectionView进行子类化。我会在下面发布最终答案。 - digitaljerry
2个回答

3

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

1)只需使红/蓝部分可点击。 这基本保持不变。我有一个对蓝色/红色视图名称 customView 的引用。

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

2)任何在UICollectionView中与蓝色/红色UIView无关的交互都应被忽略。

子类化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 上完成。同时,我们还支持可变宽度: enter image description here

1
你的回答帮了我很多,谢谢!
以下是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
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接