如何从自定义UIGestureRecognizer触发NavigationController的interactivePopGestureRecognizer

时间:2014-01-10 16:12:22

标签: ios ios7 uinavigationcontroller uigesturerecognizer

iOS 7有一个很棒的交互式动画,用于弹出UIViewControllers。通过从屏幕左侧滑动触发转换,但我想通过在视图控制器中的任意位置滑动来触发转换。 (我还想从边缘取消那些,所以我可以将它们用于另一个自定义转换......)。

到目前为止,在我的视图控制器中,我已在init中添加了此内容。我知道这是错的,我不确定我在做什么。

UIPanGestureRecognizer *panRecognizer = [[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(handleGesture:)];
panRecognizer.delegate = self.navigationController.interactivePopGestureRecognizer.delegate;
[self.view addGestureRecognizer:panRecognizer];

如何将其与内置的interactivePopGestureRecognizer绑定?应该在我的handleGesture:方法中完成吗?

修改:在Apple's documentation中,实际使用的是“领带”字样:

  

interactivePopGestureRecognizer

     

导航控制器在其视图上安装此手势识别器,并使用它将最顶层的视图控制器弹出导航堆栈。您可以使用此属性检索手势识别器,并将其与用户界面中其他手势识别器的行为联系起来。将手势识别器绑在一起时,请确保他们同时识别手势,以确保您的手势识别器有机会处理该事件。

你如何与UIGestureRecognizers结合在一起?

3 个答案:

答案 0 :(得分:5)

为什么interactivePopGestureRecognizer对于这种情况毫无价值

手势识别器有两个通知通道,即委托和目标/操作。代表用于"我是否应该考虑接受此手势"这个内部检查如下:

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{
    return !self.isAnimating &&
           self.viewControllers.count > 1 &&
           !self.navigationBarHidden &&
           [self _doesTheNavigationControllerDelegateHaveCustomTransitions] &&
           [self _someOtherSecretJunk];
}

如果测试通过,则会调用实际设置的目标/动作并为交互式过渡设置动画。

获取内置弹出交互的唯一方法是interactivePopGestureRecognizer传递其委托测试并调用操作。如果知道目标/动作是什么,我们可以尝试将其挂钩到您的自定义手势:

[[UIPanGestureRecognizer alloc] 
    initWithTarget:self.navigationController._secretGestureRecognizerTarget 
            action:@selector(_secretGestureRecognizerAction:)];

但即便如此,Apple也可能会进行无证检查:

- (void)_secretGestureRecognizerAction:(id)sender
{
    NSParameterAssert(sender == self.navigationController.interactiveGestureRecognizer);
    ...
}

你能做什么

你可以做的比你希望的要复杂得多,但却有更大的潜力。您需要创建自己的交互式过渡并将其附加到您自己的手势识别器。

您想要阅读教程并查看有关该主题的示例代码,但基本步骤如下:

  1. 创建符合UIPercentDrivenInteractiveTransition
  2. UIViewControllerAnimatedTransitioning子类
  3. 以与默认转换(或您自己的设计)的外观相匹配的方式实施animateTransition:
  4. 创建一个符合UINavigationControllerDelegate的类,并实现动画方法以及处理手势识别器的方法。
  5. 设置导航控制器以使用该委托,使用该类处理目标/操作和委托方法将手势识别器添加到视图控制器。
  6. 重要的是要注意,一旦您添加自己的自定义转换,interactivePopGestureRecognizer会有效死亡,标准交互将停止工作,因此您需要在任何地方执行自定义内容。

答案 1 :(得分:1)

我认为文档的含义是您可以使用该访问器来检索导航控制器的interactivePopGestureRecognizer,以便在您自己的识别器的委托回调中使用。例如,在-gestureRecognizer:shouldRecognizeSimultaneouslyWithGestureRecognizer:中,只有当 otherGestureRecognizer 是视图控制器的交互式弹出手势识别器时,您才可能希望返回YES

答案 2 :(得分:0)

我所做的是:

[[_myCustomRecogniser mutableArrayValueForKey:@"targets"] addObjectsFromArray:[self.navigationController.interactivePopGestureRecognizer valueForKey:@"targets"]];

Apple是否批准在App Store应用程序中使用KVC还有待观察。但它确实有效,因此显然没有进行无证的运行时检查。