最近在iOS11下发现一个问题,UIToolBar中的UIBarbuttonItem按钮不响应点击事件,调试了下发现是因为UIToolBar的父控件中添加了一个手势,按钮的点击直接去响应了父控件的手势,于是新建了一个demo,好好看下这个东西怎么回事。
代码就很简单了,toolbar上放了一个barbuttonitem
- (void)viewDidLoad {
[super viewDidLoad];
// Do any additional setup after loading the view, typically from a nib.
UIView *v = [[UIView alloc] initWithFrame:CGRectMake(0, 30, 375, 200)];
v.backgroundColor = [UIColor lightGrayColor];
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tap)];
[v addGestureRecognizer:tap];
UIToolbar *toolbar = [[UIToolbar alloc] initWithFrame:CGRectMake(0, 30, 375, 35)];
toolbar.backgroundColor = [UIColor whiteColor];
[v addSubview:toolbar];
// [toolbar layoutIfNeeded];
UIBarButtonItem *btnSpace = [[UIBarButtonItem alloc] initWithBarButtonSystemItem:UIBarButtonSystemItemFlexibleSpace target:nil action:nil];
UIBarButtonItem *sureBtn = [[UIBarButtonItem alloc] initWithTitle:@"完成 " style:UIBarButtonItemStyleDone target:self action:@selector(sureAction)];
// UIBarButtonItem *sureBtn = [[UIBarButtonItem alloc] initWithCustomView:btn]
;
[sureBtn setTitleTextAttributes:@{NSForegroundColorAttributeName:[UIColor redColor]} forState:UIControlStateNormal];
NSArray * buttonsArray = [NSArray arrayWithObjects:btnSpace,sureBtn,nil];
[toolbar setItems:buttonsArray];
[toolbar sendSubviewToBack:[toolbar.subviews lastObject]];
[self.view addSubview:v];
}
- (void)tap {
NSLog(@"tap action");
}
- (void)sureAction {
NSLog(@"confirm action");
}
运行效果如下图
实测发现,如果没有给toolbar的父控件,也就是视图v添加手势,那么按钮在iOS10和iOS11系统下都可以正常的响应点击事件,但是如果给父控件添加了手势,那么这个按钮在iOS10以下系统下可以正常响应按钮的点击事件,但是在iOS11上不能影响。
使用reveal看了看视图层级,发现iOS11系统下的UIToolBar结构复杂了很多
百度谷歌了半天,发现也有人提过这个问题。stackoverflow上的问题。虽然有人给出了不少解决方案,但是没人说出来这个到底是为啥。也许就是苹果的bug吧。这很违背响应者链条的~。
最终我选择的解决方案是把用系统方法创建的UIBarButtonItem换成了先创建一个正常的按钮,然后在使用barbuttonitem的initwithcustomview方法将按钮放入,这样可以解决问题。
UIBarButtonItem *sureBtn = [[UIBarButtonItem alloc] initWithCustomView:btn];