ios复用ViewController的,uibutton不响应事件的悲剧
站长
· 阅读数 6
背景
app中有很多介绍页面,结构都差不多。于是写了一个IntroductionViewController,用来复用。 复用的时候我直接在另一个viewController中将IntroductionViewController的实例vc的view加入self.view, 结果发现IntroductionViewController设置的按钮无法响应点击事件。
IntroductionViewController设置按钮和事件代码如下
- (**void**)setIntroTipBtns:(NSArray<NSString *> *)tipBtns titles: (NSArray<NSString *> *)tipTitles contents:(NSArray<NSString *> *)tipContents {
_introView.userInteractionEnabled = **YES**;
**for**(**int** i=0; i<tipBtns.count; i++) {
UIButton *btn = [UIButton buttonWithType:UIButtonTypeRoundedRect];
[btn setTitle:tipBtns[i] forState:UIControlStateNormal];
btn.backgroundColor = [UIColor systemCyanColor];
[_introBtns addObject:btn];
// 使用关联参数,实现uibutton多个入参
objc_setAssociatedObject(btn,"title",tipTitles[i],OBJC_ASSOCIATION_RETAIN_NONATOMIC);//实际上就是KVC
objc_setAssociatedObject(btn,"content",tipContents[i],OBJC_ASSOCIATION_RETAIN_NONATOMIC);
//这里的事件一直没办法响应
[btn addTarget:**self** action: **@selector**(showTip:) forControlEvents:UIControlEventTouchUpInside];
[_introView addSubview:btn];
//省略设置btn布局的代码
}
}
- (**void**)showTip:(UIButton *)btn{
NSString *title = objc_getAssociatedObject(btn,"title");//取参
NSString *content = objc_getAssociatedObject(btn, @"content");
[TipUtil showTip:content title:title inController:**self**];
}
**@end**
有问题的代码
原本只添加了view,无法响应点击事件。 后来直接跳转到IntroductionViewController,发现能响应点击事件。 也就是下面的代码有问题。
- (**void**)viewDidLoad {
[**super** viewDidLoad];
[**self** buildViews];
}
- (**void**)buildViews {
IntroductionViewController *vc = [[IntroductionViewController alloc] init];
[self.view addSubview:vc.view]; 无法响应IntroductionViewController中的点击事件
}
查阅资料
通过创建一个新的 IntroductionViewController
实例,并将其视图添加到当前的 UIViewController
中,然后设置 introTitleLabel
的文本和执行 setIntroTipBtns
方法。
但是,这种方式不会触发 IntroductionViewController
中按钮的点击事件,因为你只是将其视图添加到了当前 UIViewController
中,并没有建立起相应的视图控制器层级关系。
修正代码如下
- (void)buildViews {
IntroductionViewController *vc = [[IntroductionViewController alloc] init];
[self addChildViewController:vc]; // 嵌入子视图控制器
vc.view.frame = CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.height); // 设置子视图控制器的大小和位置
[self.view addSubview:vc.view];
[vc didMoveToParentViewController:self];
vc.introTitleLabel.text = @"UIAlertController介绍";
[vc setIntroTipBtns:@[@"tip1", @"tip2"] titles:@[@"tip1", @"tip2"] contents:@[@"tip1", @"tip2"]];
}