UIPageViewController手势识别器

Ric*_*man 55 uigesturerecognizer ios

我已经在申请了一段时间,但由于NDA,我无法提出这个问题.

我的Viewcontroller加载了UIPageViewController.视图控制器具有由PageViewControllers手势识别器覆盖的按钮.例如,我在viewcontroller的右侧有一个按钮,当你按下按钮时,PageViewController接管并更改页面.

如何让按钮接收触摸并取消PageViewController中的手势识别器?

我认为PageViewController使我的ViewController成为其视图的子视图.

我知道我可以关闭所有的手势,但这不是我正在寻找的效果.

宁愿不子类PageViewController苹果表示,这个类是不是要被继承.

Pat*_*McG 55

这是另一种解决方案,可以在Xcode模板viewDidLoadself.view.gestureRecognizers = self.pageViewController.gestureRecognizers部件之后立即添加到模板中.它避免弄乱手势识别器的内容或处理其代表.它只是从视图中删除了轻击手势识别器,只留下滑动识别器.

self.view.gestureRecognizers = self.pageViewController.gestureRecognizers;

// Find the tap gesture recognizer so we can remove it!
UIGestureRecognizer* tapRecognizer = nil;    
for (UIGestureRecognizer* recognizer in self.pageViewController.gestureRecognizers) {
    if ( [recognizer isKindOfClass:[UITapGestureRecognizer class]] ) {
        tapRecognizer = recognizer;
        break;
    }
}

if ( tapRecognizer ) {
    [self.view removeGestureRecognizer:tapRecognizer];
    [self.pageViewController.view removeGestureRecognizer:tapRecognizer];
}
Run Code Online (Sandbox Code Playgroud)

现在要在页面之间切换,你必须滑动.点击现在只适用于页面视图顶部的控件(这就是我所追求的).

  • 如果我们使用UIPageViewControllerTransitionStyleScroll,则self.pageViewController.gestureRecognizers为空 (12认同)
  • 我喜欢这种方法不会设置手势识别器的委托. (2认同)

小智 50

你可以覆盖

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer
 shouldReceiveTouch:(UITouch *)touch
Run Code Online (Sandbox Code Playgroud)

更好地控制PageViewController何时应该接收触摸而不是.在Dev API手势识别器中查看"防止手势识别器分析触摸"

我的解决方案在UIPageViewController的RootViewController中看起来像这样:

在viewDidLoad中:

//EDITED Need to take care of all gestureRecogizers. Got a bug when only setting the delegate for Tap
for (UIGestureRecognizer *gR in self.view.gestureRecognizers) {
    gR.delegate = self;
}
Run Code Online (Sandbox Code Playgroud)

覆盖:

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch:(UITouch *)touch {
    //Touch gestures below top bar should not make the page turn.
    //EDITED Check for only Tap here instead.
    if ([gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]]) {
        CGPoint touchPoint = [touch locationInView:self.view];
        if (touchPoint.y > 40) {
            return NO;
        }
        else if (touchPoint.x > 50 && touchPoint.x < 430) {//Let the buttons in the middle of the top bar receive the touch
            return NO;
        }
    }
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

并且不要忘记将RootViewController设置为UIGestureRecognizerDelegate.

(仅供参考,我只是在横向模式.)

编辑 - 上面的代码翻译成Swift 2:

在viewDidLoad中:

for gr in self.view.gestureRecognizers! {
    gr.delegate = self
}
Run Code Online (Sandbox Code Playgroud)

使页面视图控制器继承UIGestureRecognizerDelegate然后添加:

func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    if let _ = gestureRecognizer as? UITapGestureRecognizer {
        let touchPoint = touch .locationInView(self.view)
        if (touchPoint.y > 40 ){
            return false
        }else{
            return true
        }
    }
    return true
}
Run Code Online (Sandbox Code Playgroud)

  • 在iOS6中,`_pageViewController.gestureRecognizers`(滚动效果)是空数组,你无法处理这些识别器. (16认同)
  • 这个解决方案似乎有问题,至少在我的情况下.一旦我更改了手势识别器的委托,每次`viewControllerBeforeViewController`或`viewControllerAfterViewController`返回nil(指示最后一页)时,我开始得到`NSInvalidArgumentException`.例外原因:`提供的视图控制器数量(0)与请求的转换所需的数量(2)不匹配. (13认同)