項(xiàng)目中遇到一個(gè)頁(yè)面中是以一個(gè)scrollview橫向Tab展示兩個(gè)不同功能的顯示檐嚣,譬如消息和公告功能啰扛,但是由于滑動(dòng)返回手勢(shì)和scrollview的滑動(dòng)返回手勢(shì)沖突了,導(dǎo)致頁(yè)面不再能夠滑動(dòng)返回鞍帝。類(lèi)似的還有圖片瀏覽功能也出現(xiàn)過(guò)煞茫。
iOS系統(tǒng)中,滑動(dòng)返回手勢(shì)蚓曼,其實(shí)是一個(gè)UIPanGestureRecognizer炸宵,系統(tǒng)默認(rèn)的操作是只有滑動(dòng)屏幕的左邊的某個(gè)位置,UIPanGestureRecognizer才會(huì)起作用捎琐。UIScrollView的滑動(dòng)手勢(shì)也是UIPanGestureRecognizer。那在側(cè)邊滑動(dòng)時(shí)瑞凑,讓UIScrollView的不響應(yīng)事件就OK了嘛,首先想到了繼承UIScrollView 重寫(xiě)下面的方法练慕,讓滑動(dòng)側(cè)邊時(shí)scrollView不響應(yīng)事件技掏,根據(jù)響應(yīng)者鏈,事件最終會(huì)傳遞給下方的滑動(dòng)手勢(shì)劲阎。
- (UIView *)hitTest:(CGPoint)point withEvent:(UIEvent *)event? ? {
? ? ? if (point.x < location.x) { // location.x為系統(tǒng)的某個(gè)點(diǎn)的x
? ? ? ? ? return nil;
? ? ? } else {
? ? ? ? ? return [super hitTest:point withEvent:event];
? ? ? }
}
但是鸠真,這樣有個(gè)問(wèn)題,就是在一個(gè)頁(yè)面不同tab時(shí)锡垄,也需要滑動(dòng)切換祭隔,滑動(dòng)返回。
由于scrollView的滑動(dòng)手勢(shì)攔截了事件茴她,那我重寫(xiě)scrollView中panGestureRecognizer的代理方法程奠,讓它不攔截就好了嘛瞄沙。于是繼承UIScrollView慌核,重寫(xiě)下面的方法。
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
? ? ? ? if ([self panBack:gestureRecognizer]) {
? ? ? ? ? ? return YES;
? ? ? ? }
? ? ? ? return NO;
}
- (BOOL)panBack:(UIGestureRecognizer *)gestureRecognizer {
? ? if (gestureRecognizer == self.panGestureRecognizer) {
? ? ? ? ? UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
? ? ? ? ? CGPoint point = [pan translationInView:self];
? ? ? ? ? UIGestureRecognizerState state = gestureRecognizer.state;
? ? ? ? ? if (UIGestureRecognizerStateBegan == state || UIGestureRecognizerStatePossible == state) {
? ? ? ? ? ? ? CGPoint location = [gestureRecognizer locationInView:self];
? ? ? ? ? ? ? if (point.x > 0 && location.x < “這個(gè)自己設(shè)定" && self.contentOffset.x <= 0) {
? ? ? ? ? ? ? ? ? return YES;
? ? ? ? ? ? ? }
? ? ? ? ? }
? ? }
? ? return NO;
}
需要側(cè)邊滑動(dòng)時(shí) panBack 返回YES垫桂,這時(shí)候诬滩,我讓scrollView的手勢(shì)和頁(yè)面的滑動(dòng)返回手勢(shì)共存,scrollView不攔截手勢(shì)疼鸟,那不就可以滑動(dòng)返回了嗎。好了浩淘,測(cè)試一下吴攒,可以滑動(dòng)返回,但是滑動(dòng)返回時(shí)署惯,為什么scrollView也跟著在滑動(dòng)呢茴厉,太影響美觀了,看來(lái)還需要另外的辦法怀酷,我又回到了第一種辦法時(shí)的想法嗜闻,讓scrollView切換的時(shí)候相應(yīng)panGesture,滑動(dòng)返回的時(shí)候不響應(yīng)样眠,那重寫(xiě)scrollView中的另外一個(gè)panGestureRecognizer的代理方法翠肘。
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
? ? if ([self panBack:gestureRecognizer]) {
? ? ? ? return NO;
? ? }
? ? return YES;
}
第二種方法:
-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer?
{?
? ? // 首先判斷otherGestureRecognizer是不是系統(tǒng)pop手勢(shì)?
? ? if ([otherGestureRecognizer.view isKindOfClass:NSClassFromString(@"UILayoutContainerView")]) {?
? ? ? ? // 再判斷系統(tǒng)手勢(shì)的state是began還是fail束倍,同時(shí)判斷scrollView的位置是不是正好在最左邊?
? ? ? ? if (otherGestureRecognizer.state == UIGestureRecognizerStateBegan && self.contentOffset.x == 0) {?
? ? ? ? ? ? ? return YES;?
? ? ? ? }?
? ? }?
? ? return NO;?
}
以上的代碼都是在一個(gè)自定義的UIScrollView上的,重寫(xiě)上面的方法即可甥桂。然后讓橫向滾動(dòng)的scrollView繼承這個(gè)自定義UIScrollView就OK了邮旷。
原理:
scrollView的pan手勢(shì)會(huì)讓系統(tǒng)的pan手勢(shì)失效,所以我們只需要在系統(tǒng)手勢(shì)失效且scrollView的位置在初始位置的時(shí)候讓兩個(gè)手勢(shì)同時(shí)啟用就可以了办陷。