理解uibutton目标自我超级视图

时间:2014-11-15 15:02:35

标签: ios objective-c uiview uibutton

有人可以向我解释一下这个例子中的uibutton目标功能:

我有一个ViewController。我向这个viewcontroller添加了一个带有两个按钮的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];
}

因此,当点击在init中创建的蓝色按钮时,specialMethod会执行。当按下初始化后添加的红色应用程序时,应用程序会崩溃并显示警告 - 用于uiview的未知选择器。

我真正不理解的是,当我在init中使用NSLog [self superview]时,它是null,因为该对象尚未创建并返回到superview,但该动作由于某种原因而被执行

感谢您的帮助!

2 个答案:

答案 0 :(得分:3)

您确实为nil中的蓝色按钮添加了initWithFrameMethod目标。根据Apple的Event Handling Guide,当您添加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

答案 1 :(得分:2)

[self superview]是指向ViewController视图的指针,而不是ViewController本身。您定义为按钮操作的选择器应该以ViewController的实例为目标,而不是ViewController的视图,因为您在ViewController中定义了方法specialMethod。如果你真的想使用[self superview]作为操作的目标,那么你需要子类化UIView,实现specialMethod并将新的UIView子类设置为视图控制器的视图(不是子视图) )。这样,[self superview]将引用一个实际上在目标上指定了选择器的类。

我实际上没有尝试过您的代码示例,但它显然是错误的,如果它确实有效,那就是巧合,不应该依赖它。