問題一:和scrollView的橫滑手勢沖突
場景分析
scrollview上添加了多個頁面,橫滑實(shí)現(xiàn)切換頁面,當(dāng)滑動到第一個頁面時,右滑手勢不能打開左側(cè)菜單。
解決思路
UIView和手勢相關(guān)的方法中,除了有addGestureRecognizer和removeGestureRecognizer外,還有下面這個方法:
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer;
官方文檔中的描述
Asks the view if the gesture recognizer should be allowed to continue tracking touch events.
Subclasses may override this method and use it to prevent the recognition of particular gestures.
At the time this method is called, the gesture recognizer is in the UIGestureRecognizerStatePossible state and thinks it has the events needed to move to the UIGestureRecognizerStateBegan.
The default implementation of this method returns YES.
大概意思是:詢問視圖是否允許手勢識別器繼續(xù)跟蹤觸摸事件。子類可以重寫該方法用以阻止特定手勢的識別。這個方法調(diào)用時,手勢識別器的狀態(tài)是 UIGestureRecognizerStatePossible ,并且考慮是否有需要改變到 UIGestureRecognizerStateBegan 狀態(tài)的事件。
所以,在手勢識別器由 possible 的默認(rèn)狀態(tài)切換成 began 之前,會調(diào)用這個方法,判斷是否可以切換到 began 狀態(tài),切換到 began 狀態(tài)后,手勢識別器就會向target 發(fā)送動作消息。所以重寫該方法,針對特定的手勢,返回 NO,從而阻止手勢識別器的識別。
解決方法
直接上代碼
- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer {
if ([gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
UIPanGestureRecognizer *pan = (UIPanGestureRecognizer *)gestureRecognizer;
// 處于第一頁且向左滑時
if (self.contentOffset.x == 0 && [pan translationInView:self].x > 0) {
return NO;
}
}
return [super gestureRecognizerShouldBegin:gestureRecognizer];
}
在自定義的 UIScrollView 的子類中,重寫以上方法。判斷拖拽手勢的是否向右和 scrollView 是否已經(jīng)滑動到左邊緣,如果滿足這兩個條件,則阻止 scrollView 對拖拽手勢的識別,交給父視圖處理。
與tableViewCell的左滑手勢沖突
場景分析
項目中的 leftViewController 是一個UITableViewController 對象,cell 支持左滑刪除,但是mmDrawer中左滑 leftView 會關(guān)閉抽屜效果。
因為左滑 leftView 關(guān)閉抽屜效果,并不是必須的功能,僅需要支持點(diǎn)擊 centerView 或者左滑 centerView 關(guān)閉抽屜即可。
所以發(fā)現(xiàn)MMDrawerController 有MMCloseDrawerGestureMode屬性??梢愿淖冊搶傩?,從而改變關(guān)閉抽屜支持的手勢。
解決方法。
上代碼:
[self.drawerController setCloseDrawerGestureModeMask:MMCloseDrawerGestureModePanningCenterView|MMCloseDrawerGestureModeTapCenterView];
該屬性是枚舉類型,
typedef NS_OPTIONS(NSInteger, MMCloseDrawerGestureMode) {
MMCloseDrawerGestureModeNone = 0,
MMCloseDrawerGestureModePanningNavigationBar = 1 << 1,
MMCloseDrawerGestureModePanningCenterView = 1 << 2,
MMCloseDrawerGestureModeBezelPanningCenterView = 1 << 3,
MMCloseDrawerGestureModeTapNavigationBar = 1 << 4,
MMCloseDrawerGestureModeTapCenterView = 1 << 5,
MMCloseDrawerGestureModePanningDrawerView = 1 << 6,
MMCloseDrawerGestureModeCustom = 1 << 7,
MMCloseDrawerGestureModeAll = MMCloseDrawerGestureModePanningNavigationBar |
MMCloseDrawerGestureModePanningCenterView |
MMCloseDrawerGestureModeBezelPanningCenterView |
MMCloseDrawerGestureModeTapNavigationBar |
MMCloseDrawerGestureModeTapCenterView |
MMCloseDrawerGestureModePanningDrawerView |
MMCloseDrawerGestureModeCustom,
};
可自由選擇或組合支持的手勢,只要不支持 MMCloseDrawerGestureModePanningDrawerView ,就不會和 cell 左滑刪除產(chǎn)生沖突。
總結(jié)
使用側(cè)滑菜單,容易產(chǎn)生各種各樣的手勢沖突,所謂“做的越多,錯的越多”,支持的手勢類型越多,越容易產(chǎn)生沖突,滿足常見需求的前提下,盡量減少不需要支持的手勢。