當(dāng)你在使用UIScreenEdgePanGestureRecognizer手勢(shì)實(shí)現(xiàn)側(cè)滑的時(shí)候拉盾,如果后期你導(dǎo)航控制器push出的界面中包含UIScrollerView油湖,這個(gè)時(shí)候你會(huì)發(fā)現(xiàn)恳谎,側(cè)滑效果無法實(shí)現(xiàn)了隙疚,這個(gè)首先你會(huì)想到肯定是UIScrollerView,把這個(gè)手勢(shì)給攔截了楔脯,執(zhí)行了UIScrollerView中包含的手勢(shì)喇肋。
問題所在
滑動(dòng)返回事實(shí)上也是由于存在已久的UIScreenEdgePanGestureRecognizer來識(shí)別并且相應(yīng)地侣颂,它直接與UINavigationController的view進(jìn)行了綁定档桃,綁定的方法是寫在UINavgationController 的基類中的,正如一下:
UIPanGestureRecongnizer -- bind-- UIScrollerView
UIScreenEdgePanGestureRecognizer --bind-- UINavigationController.view
滑動(dòng)返回?zé)o法觸發(fā)憔晒,說明UIScreenEdgePanGestureRecongnizer并沒有接受到手勢(shì)事件藻肄。
根據(jù)蘋果的<a >官方文檔</a>說明 UIGestureRecongnizer 和UIview 是多對(duì)一的關(guān)系蔑舞,UIGestureRecognizer 一定要和UIView進(jìn)行綁定才能發(fā)揮作用,因此UIGestureRecongnizer對(duì)于屏幕上的手勢(shì)事件嘹屯,其接受順序和UIView的層次結(jié)構(gòu)是一致的攻询,如下關(guān)系
UINavgataionController.view -->UIviewController.view -- > UIScrollerView.view -->screen and user'finger 既UIScrollView的panGestureRecognizer
先接受到了手勢(shì)事件,直接就處理而沒有往下傳遞實(shí)際上就是兩個(gè)手勢(shì)共存的問題
解決方案
UIGestureRecognizerDelegate 代理方法中包含州弟,支持多個(gè)UIGestureRecongnizer共存钧栖,其中一個(gè)方法是
1 // called when the recognition of one of gestureRecognizer or otherGestureRecognizer would be blocked by the other
2 // return YES to allow both to recognize simultaneously. the default implementation returns NO (by default no two gestures can be recognized simultaneously)
3 //
4 // note: returning YES is guaranteed to allow simultaneous recognition. returning NO is not guaranteed to prevent simultaneous recognition, as the other gesture's delegate may return YES
5 - (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer;
總結(jié)就是此方法返回YES,手勢(shì)事件會(huì)一直往下傳遞,不論當(dāng)前層次是否對(duì)該事件進(jìn)行響應(yīng)
看看UIScrollerView的頭文件的描述:
1 // Use these accessors to configure the scroll view's built-in gesture recognizers.
2 // Do not change the gestures' delegates or override the getters for these properties.
3 @property(nonatomic, readonly) UIPanGestureRecognizer *panGestureRecognizer NS_AVAILABLE_IOS(5_0);
UIScrollView本身是其panGestureRecognizer的delegate婆翔,且apple君明確表明不能修改它的delegate(修改的時(shí)候也會(huì)有警告)
UIScrollView作為delegate拯杠,說明UIScrollView中實(shí)現(xiàn)了上文提到的shouldRecognizeSimultaneouslyWithGestureRecognizer方法,返回了NO啃奴。創(chuàng)建一個(gè)UIScrollView的category潭陪,由于category中的同名方法會(huì)覆蓋原有.m文件中的實(shí)現(xiàn),使得可以自定義手勢(shì)事件的傳遞最蕾,如下:
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer{
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] && [otherGestureRecognizer isKindOfClass:[UIScreenEdgePanGestureRecognizer class]]) {
return YES;
} else {
return NO;
}
}