問題
開發(fā)中遇到了個問題:點擊tableview的cell努隙,沒有調(diào)用didselect方法
分析原因
- 當(dāng)然先排除一些低級錯誤:是否忘了為tableview設(shè)置了代理郊尝;是否有其他view遮擋了cell玻靡;是否設(shè)置了tableview或者cell的userInteractionEnabled為NO等
排除這些之后發(fā)現(xiàn)依然沒有調(diào)用didSelect方法 - 然后去查原因,后來終于發(fā)現(xiàn)是事件響應(yīng)優(yōu)先級出了問題:
當(dāng)前View稱為AView吧,我在AView上添加了tableview违寿,點擊cell不調(diào)用didSelect方法,后來發(fā)現(xiàn)是因為我在AView的父view上添加了手勢用于收起鍵盤:
- (void)addTabGesture {
UITapGestureRecognizer *tap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(tapAction)];
tap.delegate = self;
[self addGestureRecognizer:tap];
// 監(jiān)聽鍵盤收起
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(keyboardHideFunc:) name:UIKeyboardWillHideNotification object:nil];
}
單擊事件優(yōu)先傳遞給手勢響應(yīng)熟空,如果手勢響應(yīng)識別成功藤巢,就會直接取消事件的響應(yīng)鏈傳遞。
這樣當(dāng)我點擊cell的時候息罗,點擊事件首先會被手勢識別器捕獲到掂咒,就無法再繼續(xù)執(zhí)行tableview的代理方法了
解決
》是否可以捕獲到點擊動作,在這個時候判斷點擊的是哪個view迈喉,如果是tableview的cell绍刮,就不繼續(xù)執(zhí)行tapGesture,如果不是再繼續(xù)挨摸。
》UIGestureRecognizerDelegate中有一個代理方法:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch
孩革,
官方解釋是:
called before touchesBegan:withEvent: is called on the gesture recognizer for a new touch. return NO to prevent the gesture recognizer from seeing this touch
:
在touchesBegan方法之前執(zhí)行,返回NO就可以防止手勢識別器識別到這個touch得运。
那么這個方法就可以滿足我們的需求了
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
// 獲取當(dāng)前點擊所在的view
NSString *classStr = NSStringFromClass([touch.view class]);
// 判斷是否是cell
if ([classStr isEqualToString:@"UITableViewCellContentView"]) {
return NO;
}
return YES;
}
查看tableveiwcell的層級可以發(fā)現(xiàn)膝蜈,我們點擊cell獲取到點擊事件的其實是contentView
所以代碼中要判斷所點擊view的類是否是UITableViewCellContentView锅移,自定義cell也是如此
其他
在網(wǎng)上查找的過程中,發(fā)現(xiàn)了別人由于其他原因?qū)е峦瑯訂栴}的彬檀,也寫在這里記錄一下:
- 使用xib自定義tableview帆啃,用連線方式設(shè)置代理,但是不小心線連錯了??
- 使用了xib自定義tableView窍帝,在xib中設(shè)置了tableView的selection為no selection的》掏担或者在代碼中設(shè)置了tableView的allowsSelection為NO的
- 實現(xiàn)了
willSelectRowAtIndexPath
方法:
willSelectRowAtIndexPath:(NSIndexPath *)indexPath {
return nil;
}
- 實現(xiàn)了touchesBegin方法(這個其實跟我的問題是一個原因)
- 子view的范圍超出父view的范圍
這個時候子view雖然可以正常顯示出來坤学,但范圍在父view范圍之外的部分,是完全不能響應(yīng)點擊事件的