touchesBegan 被 AppDelegate 而不是 UIView 的子类捕获
touchesBegan caught by AppDelegate instead of subclass of UIView
我正在阅读 The Big Nerd Ranch Guide 的 iOS Programming 指南(第 4 版,想要 Objective C)的第 5 章,我按照 subclassing 上的说明进行操作UIView
class 并在 AppDelegate
中添加了子视图,问题是 子视图没有捕获 touchesBegan
事件, 但是 AppDelegate
正在接收信号。
didFinishLaunchingWithOptions
中的方法 AppDelegate
:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:[UIViewController alloc]];
CGRect firstFrame = self.window.bounds;
HypnosisView *firstView = [[HypnosisView alloc] initWithFrame:firstFrame];
[self.window addSubview:firstView];
[firstView becomeFirstResponder];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
HypnosisView
的两个初始化方法,UIView
的subclass定义如下:
#import "HypnosisView.h"
@interface HypnosisView ()
@property (strong, nonatomic) UIColor *circleColor;
@end
@implementation HypnosisView
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
CGRect bounds = self.bounds;
CGRect frame = self.frame;
// Figure out the center of the bounds rectangle
CGPoint center;
center.x = frame.origin.x + frame.size.width / 2.0;
center.y = frame.origin.y + frame.size.height / 2.0;
// The largest circle will circumscribe the view
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
clockwise:YES];
}
// Configure line with to 10 points
path.lineWidth = 10;
// Configure the drawing color to light gray
[self.circleColor setStroke];
// Draw the line!
[path stroke];
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// All HypnosisViews start with a clear background color
self.backgroundColor = [UIColor clearColor];
self.circleColor = [UIColor lightGrayColor];
self.userInteractionEnabled = YES;
}
return self;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@"%@ was touched", self);
}
UIView 对象通常不会对触摸事件做出反应。您是否将您的视图的 userInteractionEnabled 标志设置为 true?
未调用的 touchesBegan 方法在哪里?
在您的 Appdelegate.m
中,您应该首先 makeKeyAndVisible
您的 window
,makeKeyAndVisible
会将 window
设置为 keyWindow
,然后将 window
放在所有 windows
.
的前面
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:[UIViewController alloc]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
CGRect firstFrame = self.window.bounds;
HypnosisView *firstView = [[HypnosisView alloc] initWithFrame:firstFrame];
[self.window addSubview:firstView];
[firstView becomeFirstResponder];
return YES;
}
我正在阅读 The Big Nerd Ranch Guide 的 iOS Programming 指南(第 4 版,想要 Objective C)的第 5 章,我按照 subclassing 上的说明进行操作UIView
class 并在 AppDelegate
中添加了子视图,问题是 子视图没有捕获 touchesBegan
事件, 但是 AppDelegate
正在接收信号。
didFinishLaunchingWithOptions
中的方法 AppDelegate
:
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:[UIViewController alloc]];
CGRect firstFrame = self.window.bounds;
HypnosisView *firstView = [[HypnosisView alloc] initWithFrame:firstFrame];
[self.window addSubview:firstView];
[firstView becomeFirstResponder];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
return YES;
HypnosisView
的两个初始化方法,UIView
的subclass定义如下:
#import "HypnosisView.h"
@interface HypnosisView ()
@property (strong, nonatomic) UIColor *circleColor;
@end
@implementation HypnosisView
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect {
CGRect bounds = self.bounds;
CGRect frame = self.frame;
// Figure out the center of the bounds rectangle
CGPoint center;
center.x = frame.origin.x + frame.size.width / 2.0;
center.y = frame.origin.y + frame.size.height / 2.0;
// The largest circle will circumscribe the view
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
clockwise:YES];
}
// Configure line with to 10 points
path.lineWidth = 10;
// Configure the drawing color to light gray
[self.circleColor setStroke];
// Draw the line!
[path stroke];
}
- (instancetype)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
// All HypnosisViews start with a clear background color
self.backgroundColor = [UIColor clearColor];
self.circleColor = [UIColor lightGrayColor];
self.userInteractionEnabled = YES;
}
return self;
}
- (void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
NSLog(@"%@ was touched", self);
}
UIView 对象通常不会对触摸事件做出反应。您是否将您的视图的 userInteractionEnabled 标志设置为 true?
未调用的 touchesBegan 方法在哪里?
在您的 Appdelegate.m
中,您应该首先 makeKeyAndVisible
您的 window
,makeKeyAndVisible
会将 window
设置为 keyWindow
,然后将 window
放在所有 windows
.
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
// Override point for customization after application launch.
self.window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.window setRootViewController:[UIViewController alloc]];
self.window.backgroundColor = [UIColor whiteColor];
[self.window makeKeyAndVisible];
CGRect firstFrame = self.window.bounds;
HypnosisView *firstView = [[HypnosisView alloc] initWithFrame:firstFrame];
[self.window addSubview:firstView];
[firstView becomeFirstResponder];
return YES;
}