一、通过视图找到控制器
- 封装分类UIView+ViewController.h
# import "UIView+ViewController.h"
@implementation UIView (ViewController)
- (UIViewController *)viewContoller {
UIResponder *next = self.nextResponder;
do {
if ([next isKindOfClass:[UIViewController class]]) {
return (UIViewController *)next;
}
next = next.nextResponder;
} while (next != nil)
return nil;
}
@end
事件传递链 Appdelegate->UIApplication->UIWindow->UIViewController->UIView-Subviews
二、封装圆形按钮点击button
- 通过
pointInside
方法修改响应范围,去除圆圈之外的范围
#import "FifthButton.h"
@implementation FifthButton
-(BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
BOOL flag = [super pointInside:point withEvent:event];
if (flag) {
//贝塞尔曲线 画出圆的范围
UIBezierPath *path =[UIBezierPath bezierPathWithOvalInRect:self.bounds];
//圆的范围是否包含点击点
if ([path containsPoint:point]) {
return YES;
}
}
return NO;
}
@end
- 调用
self.view.backgroundColor = [UIColor whiteColor];
UIButton *buttonA = [UIButton buttonWithType:(UIButtonTypeCustom)];
buttonA.frame = CGRectMake(90, 200, 90, 90);
buttonA.tag = 1001;
buttonA.backgroundColor = [UIColor purpleColor];
[buttonA addTarget:self action:@selector(buttonAction:) forControlEvents:(UIControlEventTouchUpInside)];
[self.view addSubview:buttonA];
buttonA.layer.cornerRadius = 45;
buttonA.layer.masksToBounds = YES;
-
效果图
三、扩大button的点击范围
需求扩大44 诚意44以下视图的响应范围
- 封装button,修改pointInside方法点击范围
#import "FourthButton.h"
@implementation FourthButton
- (BOOL)pointInside:(CGPoint)point withEvent:(UIEvent *)event{
CGRect bounds = self.bounds;
//若原来点击大小大于44*44保持不变,否则增长
//MAX(A,B)两个值比较,取最大值.注意NSUInteger类型
// https://www.jianshu.com/p/82a9d1ce8157
CGFloat width = MAX(44.0-bounds.size.width, 0);
CGFloat height = MAX(44.0-bounds.size.height, 0);
bounds = CGRectInset(bounds, -0.5*width, -0.5*height);
return CGRectContainsPoint(bounds, point);
}
@end
CGRectInset参考
四、子视图超出父视图无法点击
- 封装父视图
#import "ThirdButton.h"
@implementation ThirdButton
- (nullable UIView *)hitTest:(CGPoint)point withEvent:(nullable UIEvent *)event {
UIView * view = [super hitTest:point withEvent:event];
if (view == nil) {
for (UIView * subView in self.subviews) {
// 将父视图坐标系的点转换成子视图坐标系的点
CGPoint tp = [subView convertPoint:point fromView:self];
if (CGRectContainsPoint(subView.bounds, tp)) {
view = subView;
}
}
}
return view;
}
@end
- 调用
self.view.backgroundColor = [UIColor whiteColor];
ThirdButton *buttonA = [ThirdButton buttonWithType:(UIButtonTypeCustom)];
buttonA.frame = CGRectMake(0, 60, 100, 100);
buttonA.tag = 1001;
buttonA.backgroundColor = [UIColor redColor];
[buttonA addTarget:self action:@selector(buttonAction:) forControlEvents:(UIControlEventTouchUpInside)];
[self.view addSubview:buttonA];
UIButton *buttonB = [UIButton buttonWithType:(UIButtonTypeCustom)];
buttonB.frame = CGRectMake(60, 60, 200, 200);
buttonB.tag = 1002;
buttonB.alpha = 0.4;
// buttonB.userInteractionEnabled = NO;
buttonB.backgroundColor = [UIColor yellowColor];
[buttonB addTarget:self action:@selector(buttonAction:) forControlEvents:(UIControlEventTouchUpInside)];
[buttonA addSubview:buttonB];
-
效果
convertPoint参考链接
五、两个覆盖的button
需求:self.vew先加入按钮A(红色),然后加入按钮B(黄色),黄色覆盖红色,想要点击时候红色按钮红色事件响应,点击黄色黄色按钮响应。
- 封装黄色按钮
#import "MyButton.h"
// 使用全局的rect 我们利用extern关键字可以用来访问程序的全局变量;
//注释:这里的全局变量指的是,全程需只有一个的全局变量。
extern CGRect rect;
@implementation MyButton
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event {
// 判断点击的点是否在小按钮区域内
BOOL isContains = CGRectContainsPoint(rect, point);
if (isContains) {
return nil;
}
return [super hitTest:point withEvent:event];
}
@end
- 调用
//
// SecondViewController.m
// xiangyinglian
//
// Created by eport on 2021/1/8.
//
#import "SecondViewController.h"
#import "MyButton.h"
CGRect rect;
@interface SecondViewController ()
@end
@implementation SecondViewController
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view.
self.view.backgroundColor = [UIColor whiteColor];
UIButton *buttonA = [UIButton buttonWithType:(UIButtonTypeCustom)];
buttonA.frame = CGRectMake(0, 60, 100, 100);
buttonA.tag = 1001;
buttonA.backgroundColor = [UIColor redColor];
[buttonA addTarget:self action:@selector(buttonAction:) forControlEvents:(UIControlEventTouchUpInside)];
[self.view addSubview:buttonA];
MyButton *buttonB = [MyButton buttonWithType:(UIButtonTypeCustom)];
buttonB.frame = CGRectMake(0, 40, 414, 300);
buttonB.tag = 1002;
buttonB.alpha = 0.4;
// buttonB.userInteractionEnabled = NO;
buttonB.backgroundColor = [UIColor yellowColor];
[buttonB addTarget:self action:@selector(buttonAction:) forControlEvents:(UIControlEventTouchUpInside)];
[self.view addSubview:buttonB];
// 获取button1相对于button2的frame
rect = [buttonA convertRect:buttonA.bounds toView:buttonB];
}
-(void)buttonAction:(UIButton *)btn{
if (btn.tag == 1001) {
NSLog(@"红色按钮响应了");
}
else if(btn.tag == 1002){
NSLog(@"黄色按钮响应了");
}
}
@end
-
效果3
convertRect参考链接