自定义UIView不响应touchesBegan事件 · JackRo 的个人博客
作者:互联网
iOS开发中会使用到自定义UIView,下面是我在学习过程中写的一个自定义UIView:
#import "BNRHypnosisView.h"
@interface BNRHypnosisView()
@property(nonatomic, strong) UIColor *circleColor;
@end
@implementation BNRHypnosisView
- (void)setCircleColor:(UIColor *)circleColor {
_circleColor = circleColor;
[self setNeedsDisplay];
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
self.backgroundColor = [UIColor clearColor];
self.circleColor = [UIColor lightGrayColor];
//self.userInteractionEnabled = YES; //开启用户交互仍然不能响应touchesBegan事件
}
return self;
}
- (void)drawRect:(CGRect)rect {
CGContextRef cgContext = UIGraphicsGetCurrentContext();
CGRect bounds = self.bounds;
CGPoint center;
center.x = bounds.origin.x + bounds.size.width / 2.0;
center.y = bounds.origin.y + bounds.size.height / 2.0;
float maxRadius = hypot(bounds.size.width, bounds.size.height) / 2.0;
UIBezierPath *path = [[UIBezierPath alloc] init];
for (float currentRadius = maxRadius; currentRadius > 0; currentRadius -= 20) {
[path moveToPoint:CGPointMake(center.x + currentRadius, center.y)];
[path addArcWithCenter:center radius:currentRadius startAngle:0.0 endAngle:M_PI*2.0 clockwise:YES];
}
[self.circleColor setStroke];
path.lineWidth = 10.0;
[path stroke];
CGContextSaveGState(cgContext);
CGContextSetShadow(cgContext, CGSizeMake(4, 7), 3);
UIImage *logoImage = [UIImage imageNamed:@"logo.png"];
[logoImage drawInRect:rect];
CGContextRestoreGState(cgContext);
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event {
NSLog(@"%@ was touched", self);
float red = (arc4random() % 100) / 100.0;
float green = (arc4random() % 100) / 100.0;
float blue = (arc4random() % 100) / 100.0;
UIColor *randomColor = [UIColor colorWithRed:red
green:green blue:blue alpha:1.0];
self.circleColor = randomColor;
}
@end
在AppDelegate中使用这个自定义UIView,代码如下所示:
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *window in windows) {
if(window.rootViewController == nil){
UIViewController *vc = [[UIViewController alloc]initWithNibName:nil
bundle:nil];
window.rootViewController = vc;
}
}
CGRect firstFrame = self.window.bounds;
BNRHypnosisView *first 大专栏 自定义UIView不响应touchesBegan事件 · JackRo 的个人博客View = [[BNRHypnosisView alloc] initWithFrame:firstFrame];
[self.window addSubview:firstView];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
}
看似很完美的代码,但是一运行,无法响应touchesBegan事件,开始以为是没有开启用户交互,加上开启用户交互self.userInteractionEnabled = YES,仍然没用,后来有人说是这个自定义UIView视图被遮挡,导致无法响应触摸事件,给了我开启视图调试器调试看看的建议,果然,开启视图调试器看到这个自定义UIView确实被遮挡了,如下图所示:
该怎么解决呢?有人说是[self.window makeKeyAndVisible]出了问题,他会把window的rootViewController放到最前面,但我想这肯定是没读懂官方文档对makeKeyAndVisible方法的解释,如下图所示:
它是UIWindow对象的一个实例方法,是把当前window置于其他window的前面,也就是说是把整个包含了我的自定义UIView的window对象置于最前面,所以,即使注释掉这行代码,仍然无法解决我的自定义UIView被遮挡的问题。
那么问题出在哪里呢?对,问题就出在AppDelegate的下面这段代码中:
NSArray *windows = [[UIApplication sharedApplication] windows];
for(UIWindow *window in windows) {
if(window.rootViewController == nil){
UIViewController *vc = [[UIViewController alloc]initWithNibName:nil
bundle:nil];
window.rootViewController = vc;
}
}
根据上图所示官方文档对rootViewController的说明,可以知道设置了window.rootViewController会给window设定一个content view。根据视图调试器显示出来的内容,这个content view应该也就是一个UIView。所以当这个自定义的UIView添加到self.window上,代码如下所示:
CGRect firstFrame = self.window.bounds;
BNRHypnosisView *firstView = [[BNRHypnosisView alloc] initWithFrame:firstFrame];
[self.window addSubview:firstView];
这个自定义UIView就会被rootViewController设定的content view遮挡,就不能响应触摸事件了。
因此,解决这个问题修改后的关键代码如下所示:
CGRect firstFrame = self.window.bounds;
BNRHypnosisView *firstView = [[BNRHypnosisView alloc] initWithFrame:firstFrame];
[self.window.rootViewController.view addSubview:firstView];
标签:touchesBegan,自定义,JackRo,bounds,rootViewController,window,self,UIView 来源: https://www.cnblogs.com/liuzhongrong/p/12371582.html