最近在iOS11下發(fā)現(xiàn)一個問題掰伸,UIToolBar中的UIBarbuttonItem按鈕不響應點擊事件想际,調試了下發(fā)現(xiàn)是因為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");
}
運行效果如下圖
效果.png
實測發(fā)現(xiàn)侧甫,如果沒有給toolbar的父控件珊佣,也就是視圖v添加手勢,那么按鈕在iOS10和iOS11系統(tǒng)下都可以正常的響應點擊事件披粟,但是如果給父控件添加了手勢咒锻,那么這個按鈕在iOS10以下系統(tǒng)下可以正常響應按鈕的點擊事件,但是在iOS11上不能影響守屉。
使用reveal看了看視圖層級虫碉,發(fā)現(xiàn)iOS11系統(tǒng)下的UIToolBar結構復雜了很多
iOS10.png
iOS11.png
百度谷歌了半天,發(fā)現(xiàn)也有人提過這個問題胸梆。stackoverflow上的問題敦捧。雖然有人給出了不少解決方案,但是沒人說出來這個到底是為啥碰镜。也許就是蘋果的bug吧兢卵。這很違背響應者鏈條的~。
最終我選擇的解決方案是把用系統(tǒng)方法創(chuàng)建的UIBarButtonItem換成了先創(chuàng)建一個正常的按鈕绪颖,然后在使用barbuttonitem的initwithcustomview方法將按鈕放入秽荤,這樣可以解決問題。
UIBarButtonItem *sureBtn = [[UIBarButtonItem alloc] initWithCustomView:btn];