有个需求,就是需要超出视图部分上面的按钮能够响应点击事件,大概如图所示:
说一下大概情况,就是有一个容器v1(红色),上面又一个元素v2(绿色)。v2的上面又有一个元素v3(蓝色),v3有一部分超出了v2的边界,并且超出部分上面还存在一个按钮(右下角)。现在要求点击右下角按钮,能够让按钮响应事件。
绘制界面的代码如下:
do {
View1 *v = [View1 new];
self.v1 = v;
v.backgroundColor = [UIColor redColor];
[self.view addSubview:v];
[v makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(300);
make.height.equalTo(300);
make.top.equalTo(self.view);
make.centerX.equalTo(self.view);
}];
} while (0);
do {
View2 *v = [View2 new];
self.v2 = v;
v.backgroundColor = [UIColor greenColor];
[_v1 addSubview:v];
[v makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(100);
make.height.equalTo(100);
make.top.equalTo(self.view);
make.centerX.equalTo(self.view);
}];
} while (0);
do {
View3 *v = [View3 new];
self.v3 = v;
v.backgroundColor = [UIColor blueColor];
[_v2 addSubview:v];
[v makeConstraints:^(MASConstraintMaker *make) {
make.width.equalTo(100);
make.height.equalTo(100);
make.centerX.equalTo(self.view).offset(50);
make.bottom.equalTo(_v2).offset(20);
}];
} while (0);
UIButton *btn = [UIButton new];
[btn setBackgroundImage:[WJCommonUtils imageFromColor:RGBCOLOR(200, 100, 100)] forState:UIControlStateNormal];
[btn setBackgroundImage:[WJCommonUtils imageFromColor:RGBCOLOR(100, 100, 200)] forState:UIControlStateHighlighted];
[_v3 addSubview:btn];
[btn makeConstraints:^(MASConstraintMaker *make) {
make.width.height.equalTo(20);
make.right.equalTo(_v3);
make.bottom.equalTo(_v3);
}];
我们知道了iOS下的事件传递机制,因此可以通过重写view的hitTest方法来控制事件传递。因为可以这样改:
重写v1的hittest方法:
#import "View1.h"
#import "choose.h"
@implementation View1
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
NSLog(@"View1 hitTest start ");
UIView *item = [super hitTest:point withEvent:event];
if (item == self) {
NSArray *array = [choose choose:@"View3"];
if (array.count>0) {
UIView *v = (UIView *)array.lastObject;
CGPoint p = [self convertPoint:point toView: v];
item = [v hitTest:p withEvent:event];
}
}
NSLog(@"View1 hitTest - %@",item);
return item;
}
@end
搞定!