Passing selector to a custom method to create UIButton programmatically
我使用iOS7下的Xcode5做一个简单的项目。当我按下以编程方式创建的按钮时,会出现以下错误:
1 | 2013-11-10 09:16:02.969 Project2[446:70b] +[KNSunDynamicUIButton buttonSavePressed:]: unrecognized selector sent to class 0x221424 |
细节:我创建了一个自定义方法,用于以编程方式创建uibutton对象。该自定义方法用于任何视图控制器。该自定义方法需要传入参数,如x、y、width、height、button title和选择器,后者是一个事件处理程序并传入类似"(sel)选择器"。
自定义方法(属于帮助程序类):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | +(UIButton*)kNSunSetupWithSelector:(SEL)selector withX:(int)x y:(int)y width:(int)width height:(int)height buttonTitle:(NSString*)buttonTitle backGroundColor:(CGColorRef) backGroundColor { UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button setTitle:@"Save" forState:UIControlStateNormal]; button.frame = CGRectMake(x, y, width, height); button.backgroundColor = [UIColor greenColor]; // selector is used over here [button addTarget:self action:selector forControlEvents:UIControlEventTouchDown]; return button; } |
然后在一个view controller.m文件中,我调用这个自定义方法,比如:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | -(void)setUpButtons { SEL selector = @selector(buttonSavePressed:); _buttonSave = [KNSunDynamicUIButton kNSunSetupWithSelector:selector withX:470 y:410 width:160 height:40 buttonTitle:@"Save" backGroundColor:(_buttonSaveColor)]; [self.view addSubview:_buttonSave]; } @interface MyViewController () { ... // buttons UIButton* _buttonSave; } @end |
按钮事件处理程序在同一个view controller.m文件中的定义如下:
1 2 3 4 | - (void)buttonSavePressed:(UIButton*)button { NSLog(@"Button Save clicked."); } |
当我运行代码并点击按钮时,我看到上面提到的异常。请帮忙谢谢。
p.s.如果我将自定义方法重写为在其签名中没有"(sel)selector"参数的替代方法,并让调用该自定义方法的控制器视图执行对选择器进行编码的操作,则没有例外:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | -(void)setUpButtons { //Note: the codes are in my view controller .m file _buttonSave = [KNSunDynamicUIButton kNSunSetupWithX:470 y:410 width:160 height:40 buttonTitle:@"Save" backGroundColor:_buttonSaveColor]; // Note: selector coding is taken care by codes of my view controller instead of by custom method [_buttonSave addTarget:self action:@selector(buttonSavePressed:) forControlEvents:UIControlEventTouchDown]; [self.view addSubview:_buttonSave]; [_buttonSave setupView]; } |
以及可选的自定义方法(我不喜欢该方法,因为它不考虑动态传入选择器):
1 2 3 4 5 6 7 8 9 10 11 | +(UIButton*)kNSunSetupWithX:(int)x y:(int)y width:(int)width height:(int)height buttonTitle:(NSString*)buttonTitle backGroundColor:(CGColorRef) backGroundColor { UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button setTitle:@"Save" forState:UIControlStateNormal]; button.frame = CGRectMake(x, y, width, height); button.backgroundColor = [UIColor greenColor]; return button; } |
帮助程序类中的行有问题:
1 | [button addTarget:self action:selector forControlEvents:UIControlEventTouchDown]; |
这里,您说助手类将具有您正在通过选择器传递的方法,在您的情况下是
您应该在自己的helper方法中添加in controller参数,以告诉您选择方法放在哪个控制器中。
在您的特定情况下,helper方法应该如下所示(注意,incontroller参数是在selector参数之后添加的):
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | +(UIButton*)kNSunSetupWithSelector:(SEL)selector inController:(UIViewController*)controller withX:(int)x y:(int)y width:(int)width height:(int)height buttonTitle:(NSString*)buttonTitle backGroundColor:(CGColorRef) backGroundColor { UIButton* button = [UIButton buttonWithType:UIButtonTypeRoundedRect]; [button setTitle:@"Save" forState:UIControlStateNormal]; button.frame = CGRectMake(x, y, width, height); button.backgroundColor = [UIColor greenColor]; // selector is used over here [button addTarget:controller action:selector forControlEvents:UIControlEventTouchDown]; return button; } |
你应该这样称呼它,从你的控制器:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 | -(void) setupButtons { SEL selector = @selector(buttonSavePressed:); _buttonSaveColor = [UIColor orangeColor].CGColor; _buttonSave = [KNSunDynamicUIButton kNSunSetupWithSelector:selector inController:self withX:470 y:410 width:160 height:40 buttonTitle:@"Save" backGroundColor:(_buttonSaveColor)]; [self.view addSubview:_buttonSave]; } |