// LZRedBtn.h
#import <UIKit/UIKit.h>
@interface LZRedBtn : UIButton
@end
// LZRedBtn.m
#import "LZRedBtn.h"
@implementation LZRedBtn
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@"%s",__func__);
}
@end
// GreenView.h
#import <UIKit/UIKit.h>
@interface GreenView : UIView
@end
// GreenView.m
#import "GreenView.h"
#import "LZRedBtn.h"
@interface GreenView ()
@property(nonatomic, weak) IBOutlet LZRedBtn *redBtn;
@end
@implementation GreenView
/**
* 要完成一个穿透效果很简单,先观察谁在上面,比如有1号,2号,1号假设在2号上面,那么就在
storyboard里面拖一个1号对应的控件,用1号自定义的类去修饰,这样才能重写hitTest方法,
然后2号对应的控件就拖拽到1号底部,遮盖嘛,1号同时设置一下透明度,显示部分2号内容,然后
在1号自定义的类里面添加一个2号对应的属性,给storyboard托线,描述2号控件,就前期准备工作
做好了,然后重写hitTest方法就是了,判断1号上面的点在不在2号的上面,如果在,返回2号控件,
不在的话,那么就按照系统默认做法,调用super方法,注意判断点的时候,要把传人的点转化为2号
控件所描述的坐标系,也很容易理解嘛,要是不转,也太一帆风顺了,总要有点难度吧
*/
// 当一个事件传递给当前view调用
// 寻找最合适的view
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event
{
//判断当前点在不在按钮身上.
//把当前点转换成按钮坐标系上面的点
CGPoint redBtnP = [self convertPoint:point toView:self.redBtn];
// 如果self.redBtn包含了redBtnP
if ([self.redBtn pointInside:redBtnP withEvent:event]) {
NSLog(@"redBtn");
return self.redBtn;
} else {
return [super hitTest:point withEvent:event];
}
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"%s",__func__);
}
@end
效果图片:
2.png
3.png
5.png
6.png
网友评论
{
//判断当前点在不在按钮身上.
//把当前点转换成按钮坐标系上面的点
CGPoint redBtnP = [self convertPoint:point toView:self.redBtn];
// 如果self.redBtn包含了redBtnP
if ([self.redBtn pointInside:redBtnP withEvent:event] || [self pointInside:point withEvent:event]) {
return self.redBtn;
} else {
return [super hitTest:point withEvent:event];
}
}
{
return self.redBtn;
}