简体   繁体   English

将UICollectionView的某些部分上的触摸传递给基础视图

[英]Pass touches on some part of UICollectionView to underlying views

First take a look at the attacthed image: 首先看一下附加的图像: 在此处输入图片说明

My hiearchy looks as following: 我的hiearchy如下所示:

  • UIView 的UIView
    • UIButton 的UIButton
    • UICollectionView UICollectionView
      • UICollectionViewCell UICollectionViewCell
      • UICollectionViewCell UICollectionViewCell
      • UICollectionViewCell UICollectionViewCell
      • UICollectionViewCell UICollectionViewCell

UICollectionView is added to UIVew as H:[collectionView(==270)]| UICollectionView作为H:[collectionView(==270)]|添加到UIVew中H:[collectionView(==270)]| and V:|-(70)-[collectionView]-(70)-| V:|-(70)-[collectionView]-(70)-| .

I have two requirements: 我有两个要求:

1) only the blue part of the UICollectionViewCell should trigger the collectionView::didSelectItemAtIndexPath: method. 1)仅UICollectionViewCell的蓝色部分应触发collectionView::didSelectItemAtIndexPath:方法。 Which I have sucesfully implemented with 我已经成功实现了

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

on the custom class UIColectionViewCell. 在自定义类UIColectionViewCell上。 The customView property is the blue/red UIView of the cell. customView属性是单元格的蓝色/红色UIView。 This works as expected. 这按预期工作。

2) I want any gestures (Tap/LongTap/Pan/...) that are done in the green part of the UICollectionViewCell or in the UICollectionVIew itself (the background that is here white with 0.5 opacity) to be passed down to the superview. 2)我希望在UICollectionViewCell的绿色部分或UICollectionVIew本身(此处背景为白色,不透明度为0.5的白色)中完成的任何手势(Tap / LongTap / Pan / ...)都向下传递到超级视图。 For Example the turquoise UIButtion below. 例如下面的绿松石UIButtion。 The green part should also not scroll the CollectionView .. it just has to be completly transparent to any gestures. 绿色部分也不应滚动CollectionView ..它只必须完全透明于任何手势。

How can I do that? 我怎样才能做到这一点? Tried a lot of different approaches but none of them worked. 尝试了许多不同的方法,但没有一个起作用。 I know how to do it with a regular UIView, but cannot get it to work on a UICollectionView and its cells. 我知道如何使用常规的UIView进行操作,但是无法使其在UICollectionView及其单元上工作。

Keep in mind that there will be other UIViews or UIButtions that will be interactable and placed under the green part of collection view. 请记住,还会有其他UIViews或UIButtions可以交互并放置在集合视图的绿色部分下。 The green color will later just be UIClearColor. 以后,绿色将只是UIClearColor。

Suggestion to just have the UICollectionView smaller width (width of the blue part) is not an option since the Blue/Red part of UICell has to strecth out to full width of the cell in some cases. 建议不要让UICollectionView的宽度更小(蓝色部分的宽度),因为在某些情况下,UICell的蓝色/红色部分必须伸到整个单元格的宽度。

Here is the final solution for above example: 这是上述示例的最终解决方案:

1) Require only red/blue part to be tappable. 1)仅需点击红色/蓝色部分即可。 This stays basically the same. 这基本保持不变。 I have a reference to the blue/red UIView names customView 我引用了蓝色/红色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) Any interactions inside the UICollectionView that are not done on blue/red UIViews should be ignored. 2)应该忽略在UICollectionView内部没有在蓝色/红色UIView上进行的任何交互。

Subclassing UICollectionView and adding overwriting this metod: 子类化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;
}

This will check if the CGPoint is done on the customView . 这将检查CGPoint是否在customViewcustomView With this we are also supporting variable widths: 我们也支持可变宽度:

在此处输入图片说明

Your answer helped me a ton, thanks! 您的回答帮助了我很多,谢谢!

Here's the solution in Swift 3.0: 这是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
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM