将 UICollectionView 的某些部分的触摸传递给底层视图
Pass touches on some part of UICollectionView to underlying views
先看看附件图:
我的层次结构如下所示:
- UIView
- UIButton
- UICollectionView
- UICollectionViewCell
- UICollectionViewCell
- UICollectionViewCell
- UICollectionViewCell
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
}
先看看附件图:
我的层次结构如下所示:
- UIView
- UIButton
- UICollectionView
- UICollectionViewCell
- UICollectionViewCell
- UICollectionViewCell
- UICollectionViewCell
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
}