将 UICollectionView 触摸事件传递给其父 UITableViewCell
Posted
技术标签:
【中文标题】将 UICollectionView 触摸事件传递给其父 UITableViewCell【英文标题】:Pass UICollectionView touch event to its parent UITableViewCell 【发布时间】:2015-11-04 01:47:08 【问题描述】:这是视图结构:
外部视图是UITableView
。
在UITableViewCell
内部,有一个UICollectionView
。请注意,集合视图单元格之间有一些黑色间距。
当我点击 UICollectionView 中的间距时,我希望触摸事件传递给 UITableViewCell
。
【问题讨论】:
【参考方案1】:@tounaobun 的出色回答。经过测试,它按预期工作:
1) 如果您点击集合视图上不是项目的任何位置,那么下面的表格单元格将被选中。
2) 如果您点击集合视图中的项目,则表格单元格将不会被选中,您可以正常与集合视图交互(也就是滚动、调用 didSelectItem 等)
我转成swift供参考:
斯威夫特 3:
class TableCellCollectionView: UICollectionView
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView?
if let hitView = super.hitTest(point, with: event)
if hitView is TableCellCollectionView
return nil
else
return hitView
else
return nil
只需将这个类定义添加到您的代码中(我在实用程序文件中有它),然后将集合视图的类从 UICollectionView 更改为 TableCellCollectionView,您应该一切就绪。
【讨论】:
我有类似的情况:另一个 UICollectionViewCell 内部的 UICollectionViewCell。但是,我只能从包含另一个单元格的单元格中检测到点击(通过 didSelectItem 委托方法)。但我需要检测来自内部单元的水龙头。这不起作用。 @vikzilla 你找到解决方案了吗?我也有同样的问题。 @William 很好的解决方案,明白这一点的人一定会受益,因为这是解决上述问题的完美解决方案。【参考方案2】:google了一下,找到了解决办法,继承UICollectionView
类,重写hitTest:withEvent
方法即可。
CustomCollectionView.h
@interface CustomCollectionView : UICollectionView
@end
CustomCollectionView.m
@implementation CustomCollectionView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
UIView *hitView = [super hitTest:point withEvent:event];
if ([hitView isKindOfClass:[self class]])
// If it is class UICollectionView,just return nil.
return nil;
// else return super implementation.
return [super hitTest:point withEvent:event];
@end
【讨论】:
【参考方案3】:最高投票答案的代码可以轻松缩短。
斯威夫特 4.1:
final class InteractiveCollectionView: UICollectionView
override func hitTest(_ point: CGPoint, with event: UIEvent?) -> UIView?
return super.hitTest(point, with: event) as? InteractiveCollectionView
【讨论】:
这种简化是错误的,CollectionView 命中应该返回nil。但是,此代码返回的是找到的 CollectionView,因此不允许父级处理点击。【参考方案4】:您可以覆盖UICollectionView
的point(inside:with:)
方法,并手动检查是否有任何单元格包含指定点:
class CollectionView: UICollectionView
override func point(inside point: CGPoint, with event: UIEvent?) -> Bool
visibleCells.contains(where: $0.frame.contains(point) )
【讨论】:
【参考方案5】:是否可以将collectionView的backgroundView UserInteraction设置为不启用,但确保collectionViewCell启用,以便它可以将tapEvent传递给下一个响应者。
- (void)viewDidLoad
theCollectionView.userInteractionEnabled = NO;
我希望它会有所帮助。
【讨论】:
这样 UICollectionViewCell 无法响应用户交互。以上是关于将 UICollectionView 触摸事件传递给其父 UITableViewCell的主要内容,如果未能解决你的问题,请参考以下文章
如何将触摸事件传递给 parentViewController?