UILongPressGestureRecognizer長按事件不響應(yīng),只有手指移動和手指松開時長按事件才會被執(zhí)行

最近發(fā)現(xiàn)項目中有多處列表頁都不能側(cè)滑返回,公司沒有產(chǎn)品經(jīng)理,這樣對于8P這樣的屏幕體驗非常的差, 我就添加統(tǒng)一的側(cè)滑返回,期間遇到遇見一個有關(guān)長按手勢不執(zhí)行的問題。

問題描述:

給UITableView的cell添加了長按手勢,當長按cell時UILongPressGestureRecognizer事件不響應(yīng),只有手指移動和手指松開時長按事件才會被執(zhí)行

問題排查

初步判斷多個手勢沖突, 問題應(yīng)該由添加側(cè)滑返回的代碼出現(xiàn)了問題,側(cè)滑返回我使用了UINavigationController+TZPopGesture分類,通過一個方法即可實現(xiàn)。
查看其實現(xiàn),發(fā)現(xiàn)它是給scrollView添加一個UIPanGestureRecognizer拖動手勢,當這個拖動手勢響應(yīng)時,執(zhí)行navigationController的側(cè)滑返回手勢,觸發(fā)側(cè)滑返回,
另外還在UINavigationController中 實現(xiàn)了self.interactivePopGestureRecognizer.delegate;
我發(fā)現(xiàn)問題應(yīng)該出在這塊,便注釋了部分手勢的代理方法,發(fā)現(xiàn)tableViewCell的長按手勢可正常響應(yīng)了;
最終確定問題發(fā)生在- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer方法內(nèi), 最初的時候為了解決只有在系統(tǒng)側(cè)滑手勢失敗時,才去觸發(fā)ScrollView的滑動,此方法return YES;

此方法有兩個參數(shù)為兩個手勢,意思為只有當gestureRecognizer被判斷偵測失敗了,才可以偵測otherGestureRecognizer,
當我長按cell時,長按手勢為otherGestureRecognizer,而此時gestureRecognizer為我們?yōu)閟crollView添加的拖動手勢,那此時拖動手勢并沒有失敗,所以長按手勢不會被執(zhí)行到,但當手指移動或松開時gestureRecognizer被偵測失敗,此時otherGestureRecognizer長按手勢才會被偵測到;

解決方法

處理添加的側(cè)滑返回手勢和長按手勢沖突,當當前手勢gestureRecognizer是側(cè)滑返回手勢時,同時處理otherGestureRecognizer

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {
    // 此處導致使用此分類的界面長按時不能及時響應(yīng),只有手指移動、松開手指時才會響應(yīng)長按手勢
    UIViewController *vc = self.topViewController;
    if ([gestureRecognizer isEqual:vc.tz_popGestureRecognizer]) {
        return NO;
    }
    return YES;
}

總結(jié)

  • 通過Xcode文檔發(fā)現(xiàn),這兩個api是在iOS7時添加的
// called once per attempt to recognize, so failure requirements can be determined lazily and may be set up between recognizers across view hierarchies
// return YES to set up a dynamic failure requirement between gestureRecognizer and otherGestureRecognizer
//
// note: returning YES is guaranteed to set up the failure requirement. returning NO does not guarantee that there will not be a failure requirement as the other gesture's counterpart delegate or subclass methods may return YES
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);
  • 說明
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRequireFailureOfGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);

此方法指定只有g(shù)estureRecognizer被系統(tǒng)判定失敗時,才會執(zhí)行otherGestureRecognizer

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer NS_AVAILABLE_IOS(7_0);

此方法指定只有otherGestureRecognizer被系統(tǒng)判定失敗時,才會執(zhí)行g(shù)estureRecognizer

由于這兩個方法比較相似,所以用的時候還是要注意使用場景,不要弄混了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容