- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
- 往下传递(superview):return nil
- 往上传弟(subview):returen [super hitTest:point withEvent:event];
- 自己消化,停止传递:return self
情况一
[黄色view addSubview:白色view]- 添加4个粉色button:
[白色view addSubview:粉色button] - 白色view中有一些pink button可以点击
- 但是如果触摸事件发生在白色view的空白区域,则需要把事件往下传递到黄色view
// 白色view重写该方法,以便实现触摸空白区域时,可以将触摸事件往下传递。self就是白色view
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
for (UIView *pinkButton in self.subviews) {
CGPoint convertPoint = [self convertPoint:point toView:pinkButton];
if (CGRectContainsPoint(pinkButton.bounds, convertPoint)) {
// pinkButton可以接收这个事件,则需要让这个事件继续hitTest(往上)
return [super hitTest:point withEvent:event];
}
}
return nil; // 无子视图接收这个事件,自己也不需要接收这个事件,返回nil,这便传递到了黄色区域
}
情况二
情况背景和要求:
- 因为某些极端场景的效率要求,越少添加触摸事件,效率越高;
- 因为代码比较陈旧,粉色方框是用UIView一个一个的布局上的,而非使用collectionView
- 点击任意粉色方框可以触发同一个action:pinkAction
- 点击白色背景要求触摸事件可以传递到黄色视图(或者称之为事件穿透)
- 如何只在白色视图上添加一个触摸事件,即可以达到这个效果。
/// 白色视图需要重写 hitTest:withEvent:
@interface WYWhiteView : UIView
@end
@implementation WYWhiteView
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
for (UIView *pinkview in self.pinkViews) {
CGPoint convertPoint = [self convertPoint:point toView:pinkview];
if (CGRectContainsPoint(pinkview.bounds, convertPoint)) {
// 点击在了pinkview范围内,则自己消化这次点击事件
return self;
}
}
return nil; // 点击在其它空白地方,则不接收这次点击事件
}
@end
TODO
- 如何解释 pointInside 不能否完成这件事
- 是否还有其它方式完成这件事?
一些其它参考
- iOS-hitTest:withEvent与自定义hit-testing规则www.jianshu.com/p/e08b80856…