有人可以向我解释此示例中的uibutton目标功能吗:
我有一个视图控制器。我向此视图控制器添加了一个带有两个按钮的 uiview。一个按钮在 init 中装箱,另一个由方法"addSecondButton"创建。这两个按钮在[self superview]目标(即ViewController)上具有相同的操作。代码:
ViewController.m
- (void)viewDidLoad {
[super viewDidLoad];
MySpecialView *myspecialview = [[MySpecialView alloc] initWithFrame:self.view.frame];
[self.view addSubview:myspecialview];
[myspecialview addSecondButton];
}
- (void)specialMethod { NSLog(@"right here!"); }
MySpecialView.m
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:frame];
if (self) {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 30, frame.size.width, 50)];
[button addTarget:[self superview] action:@selector(specialMethod) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor blueColor];
[self addSubview:button];
}
return self;
}
- (void)addSecondButton {
UIButton *button = [[UIButton alloc] initWithFrame:CGRectMake(0, 90, self.frame.size.width, 50)];
[button addTarget:[self superview] action:@selector(specialMethod) forControlEvents:UIControlEventTouchUpInside];
button.backgroundColor = [UIColor redColor];
[self addSubview:button];
}
因此,当点击在初始化中创建的蓝色按钮时,specialMethod 确实会执行。当按下在初始化后添加的红色时,应用程序崩溃并显示警告 - uiview 的未知选择器。
我真正不明白的是,当我在 init 中 NSLog [self superview] 时,它是空的,因为对象尚未创建并返回到超级视图,但由于某种原因,该操作确实被执行了。
感谢您的帮助!
您确实为 initWithFrameMethod
中的蓝色按钮添加了nil
目标。根据 Apple 的事件处理指南,当您添加nil
目标时,消息(在您的情况下specialMethod
)将通过响应器链传递:
When the user manipulates a control, such as a button or switch, and the target for the action method is nil, the message is sent through a chain of responders starting with the control view.
由于您的ViewController
是响应程序链的一部分,因此它将接收此消息并调用其specialMethod
。
[self superview]
是指向ViewController视图的指针,而不是ViewController本身。 您定义为按钮操作的选择器应针对 ViewController 的实例,而不是 ViewController 的视图,因为您在 ViewController 中定义了specialMethod
方法。 如果您确实想使用 [self superview]
作为操作的目标,则需要对 UIView 进行子类化,实现specialMethod
并将新的 UIView 子类设置为视图控制器的视图(而不是子视图)。 这样,[self superview]
将引用一个类,该类实际上在目标上指定了选择器。
我实际上并没有尝试过您的代码示例,但它显然是错误的,如果它确实有效,那是巧合,不应该依赖。