简体   繁体   English

防止超级视图识别平移手势(在iOS 7中)

[英]Prevent the superview recognizing the pan gesture (in iOS 7)

I have implemented a Side Bar NavigationController , which consists of a front and a rear ViewController . 我已经实现了一个侧边栏NavigationController ,它由一个前面的ViewController和一个后面的ViewController This Side Bar NavigationController does make use of pan and swipe gesture recognizers to let the user toggle between the front and the rear view. 此侧边栏NavigationController确实使用了平移和滑动gesture recognizers以使用户在前视图和后视图之间切换。 It works fine. 工作正常。 But using a TableView in the front ViewController causes an annoying behaviour. 但是在前面的ViewController使用TableView会导致令人讨厌的行为。 Everytime I scroll in the table view, the pan gesture recognizer of my Side Bar NavigationControllers recognizes the horizontal movement of my finger and moves the front view controller accordingly. 每当我在表格视图中滚动时,侧边栏NavigationControllers的平移手势识别器都会识别手指的水平移动并相应地移动前视图控制器。

Now, here is my question: Is it possible to prevent the superview (Side Bar NavigationController's view) recognizing the pan gesture as I scroll in the table view? 现在,这是我的问题:当我在表格视图中滚动时,是否可以防止超级视图(侧栏NavigationController's视图)识别出摇动手势? It somehow works fine with the back swipe gesture of the navigation controller, since as swiping back (from left to right) my Side Bar NavigationController does not recognize the pan gesture. 它在某种程度上可以与导航控制器的向后滑动手势一起使用,因为向后滑动(从左向右)时,我的侧边栏NavigationController无法识别平移手势。 It also works perfectly with a UISlider in the front view. 它也可以与前视图中的UISlider完美配合。 So, I can move the thumb of the slider from left to the right and my Side Bar NavigationController does not recegnize the pan gesture at all. 因此,我可以从左向右移动滑块的拇指,而我的侧边栏NavigationController根本无法识别平移手势。 So, somehow the slider prevents forwarding the touch events to its superviews. 因此,滑块会以某种方式阻止将触摸事件转发到其超级视图。 How can I achieve the same with the table view? 如何在表格视图中实现相同目的?

Try some of the following: 尝试以下方法:

  • Set the gesture delegate and prevent the 2 gestures to be recognised simultaneously 设置手势代表并防止同时识别2个手势
  • Implement UIScreenEdgePanGestureRecognizer 实现UIScreenEdgePanGestureRecognizer
  • In gesture delegate check the location of the gestures when the state is UIGestureRecognizerStateBegan and call both gesture.enabled = NO; gesture.enabled = YES; 在手势委托中,当状态为UIGestureRecognizerStateBegan时,请检查手势的位置,并同时调用两个gesture.enabled = NO; gesture.enabled = YES; gesture.enabled = NO; gesture.enabled = YES; to break gesture recognising in cases where the location is in table view. 在位置位于表格视图中的情况下中断手势识别。

Unfortunately each of the approaches might have side affects though. 不幸的是,每种方法都有副作用。

I had the same problem in one of my earlier projects. 在我的早期项目之一中,我遇到了同样的问题。

I ended up overriding shouldBeRequiredToFailByGestureRecognizer in the view controller (UIGestureRecognizerDelegate function) to prevent an other view from stealing my gestures 我最终在视图控制器中覆盖了shouldBeRequiredToFailByGestureRecognizer (UIGestureRecognizerDelegate函数),以防止其他视图窃取我的手势

//Prevents the map from stealing gestures from headerview
- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldBeRequiredToFailByGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer {

    if(gestureRecognizer is your gesture)
        return YES;

    return NO;
}

Remember to set the delegate of your gesture recognizers! 请记住设置手势识别器的代表!

I modified the gesture recognition implemented in my SideBarNavigationController and I am now able to achieve the desired behaviour. 我修改了在SideBarNavigationController中实现的手势识别,现在可以实现所需的行为。

So, I only had to change the implementation of the delagate method gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:. 因此,我只需要更改脱位方法gestureRecognizer:的实现,就应该同时使用GestureRecognizer:来识别。 Before, it simply returned YES, so that the SideBarNavigationController could detect swipe and pan gesture simultaneously. 以前,它只是返回YES,以便SideBarNavigationController可以同时检测滑动和平移手势。 Now the implementation is changed to the following: 现在,实现更改为以下内容:

- (BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldRecognizeSimultaneouslyWithGestureRecognizer:(UIGestureRecognizer *)otherGestureRecognizer
{
    BOOL shouldRecognize = NO;

    if (  (  (gestureRecognizer == _rightSwipeGestureRecognizer)
           ||(gestureRecognizer == _leftSwipeGestureRecognizer)
           ||(gestureRecognizer == _panGestureRecognizer))
        &&(  (otherGestureRecognizer == _rightSwipeGestureRecognizer)
           ||(otherGestureRecognizer == _leftSwipeGestureRecognizer)
           ||(otherGestureRecognizer == _panGestureRecognizer)))
    {
        shouldRecognize = YES;
    }

    return shouldRecognize;
}

The method now checks if the two given gesture recognizers are equal to those created in my SideBarNavigationController. 现在,该方法检查两个给定的手势识别器是否等于在我的SideBarNavigationController中创建的手势识别器。 If so, the method returns YES. 如果是这样,则该方法返回“是”。 Otherwise, if one of the gesture recognizers is coming from another view, like the table view, the methoed returns NO, so that the SideBarNavigationController stopps detecting the swipe and pan gestures. 否则,如果一个手势识别器来自另一个视图(如表格视图),则方法将返回NO,以便SideBarNavigationController停止检测滑动手势和平移手势。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM