在ios6中,将pageViewController的gestureRecognizers委托设置为viewController会导致崩溃

noR*_*ema 8 xcode objective-c ios ios6

这只是在ios6上开始发生,但是如果你使用页面视图控制器模板启动一个新项目.然后进去

PCRootViewControlle::viewDidLoad()
Run Code Online (Sandbox Code Playgroud)

将行添加到方法的底部.

for (UIGestureRecognizer *gR in self.pageViewController.gestureRecognizers)
{
    gR.delegate = self;
}
Run Code Online (Sandbox Code Playgroud)

您需要分配viewController以使其符合UIGestureRecognizerDelegate并实现该方法

-(BOOL)gestureRecognizer:(UIGestureRecognizer *)gestureRecognizer shouldReceiveTouch (UITouch *)touch
{
    return YES;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果您运行应用程序并尝试将页面超出界限,即转到1月并尝试返回

  • (UIViewController*)pageViewController:(UIPageViewController*)pageViewController viewControllerBeforeViewController:(UIViewController*)viewController

返回零.

该应用程序将崩溃.

ios5没有发生这种情况.我需要将gestureRecognizer委托分配给我的viewController,因为我并不总是希望pageViewController处理触摸事件.

有没有其他人经历过这个或指出如果我做错了什么?

非常感谢斯图尔特.

noR*_*ema 8

终于找到了我的问题的解决方案,这让我感到悲伤,所以希望这可以帮助别人.

问题是如果将pageViewControllers委托设置为viewController

for (UIGestureRecognizer *gR in self.pageController.view.gestureRecognizers) 
{
    if ([gR isKindOfClass:[UITapGestureRecognizer class]])
    {
        gR.enabled = NO;
    }
    else if ([gR isKindOfClass:[UIPanGestureRecognizer class]])
    {
        gR.delegate = self;
    }
}
Run Code Online (Sandbox Code Playgroud)

然后返回零

pageViewController:viewControllerAfterViewController:
Run Code Online (Sandbox Code Playgroud)

会崩溃!! 仅限iOS6 !!

我的问题是我需要设置gestureRecognisers的委托,因为我需要在某些情况下拦截panGesture,即不允许用户翻页,因为那里有一些按钮触摸它的某些部分.

解决方案是从逻辑出发

pageViewController:viewControllerAfterViewController: 
Run Code Online (Sandbox Code Playgroud)

gestureRecognizer:shouldReceiveTouch:
Run Code Online (Sandbox Code Playgroud)

因为只要我们从那里返回NO,它就不会继续打电话

pageViewController:viewControllerAfterViewController:
Run Code Online (Sandbox Code Playgroud)

所以不需要返回nil并且崩溃.

但是,这在序列的第一页和最后一页上不起作用.例如,在第一页上,您希望允许页面向前但不向后.所以我想看看传入的GestureRecogniser,将其投射到PanGesture,然后检查速度,如果速度表示转回(> 0.0f),则返回NO.听起来不错,但速度始终为零.

然后我在GestureRecognizer委托上找到了一个非常有用的小功能:

gestureRecognizerShouldBegin:gestureRecognizer
Run Code Online (Sandbox Code Playgroud)

之后调用此函数

gestureRecognizer:shouldReceiveTouch:
Run Code Online (Sandbox Code Playgroud)

但是这次来自手势的速度是我预期的,所以我可以检查速度,如果它> 0.0f,则只返回第一页的YES


jan*_*ins 7

我相信我已经找到了解决办法,这比任何重构现有pageViewController代码,noRema提及,或选择转发搞乱,如前所述曲少得多这里,但我永远不会发现它没有这两个解决方案作为参考.

这应该很容易放入任何UIPageViewController项目,只需稍作调整.

要实现,您可以按原样保留代码; 所有现有逻辑应保持不变,因为这只会影响UIGestureRecognizer Delegate行为.覆盖手势委托方法 - (BOOL)gestureRecognizerShouldBegin:具有如下内容:

注:我使用的是苹果公司的网页为基础的应用程序代码为出发点,因此是指,如果条款_modelController_pageViewController造成任何混乱.

- (BOOL)gestureRecognizerShouldBegin:(UIGestureRecognizer *)gestureRecognizer
{

    //Make sure we're not trying to turn backward past the first page:
    if ([_modelController indexOfViewController:[_pageViewController.viewControllers objectAtIndex:0]] == 0) {
        if ([(UIPanGestureRecognizer*)gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] &&
            [(UIPanGestureRecognizer*)gestureRecognizer velocityInView:gestureRecognizer.view].x > 0.0f) {
            NSLog(@"DENIED SWIPE PREVIOUS ON FIRST PAGE");
            return NO;
        }
        if ([(UITapGestureRecognizer*)gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] &&
            [(UITapGestureRecognizer*)gestureRecognizer locationInView:gestureRecognizer.view].x < self.view.frame.size.width/2) {
            NSLog(@"DENIED TAP PREVIOUS ON FIRST PAGE");
            return NO;
        }
    }

    //Make sure we're not trying to turn forward past the last page:
    int finalVCindexSubtractor;
    if (UIInterfaceOrientationIsLandscape(self.interfaceOrientation)) {
        // the vc we compare is a different distance from the end based on our orientation:
        finalVCindexSubtractor = 2;
    } else {
        finalVCindexSubtractor = 1;
    }
    if ([_modelController indexOfViewController:[_pageViewController.viewControllers objectAtIndex:0]] == _modelController.pageData.count-finalVCindexSubtractor) {
        if ([(UIPanGestureRecognizer*)gestureRecognizer isKindOfClass:[UIPanGestureRecognizer class]] &&
            [(UIPanGestureRecognizer*)gestureRecognizer velocityInView:gestureRecognizer.view].x < 0.0f) {
            NSLog(@"DENIED SWIPE NEXT ON LAST PAGE");
            return NO;
        }
        if ([(UITapGestureRecognizer*)gestureRecognizer isKindOfClass:[UITapGestureRecognizer class]] &&
            [(UITapGestureRecognizer*)gestureRecognizer locationInView:gestureRecognizer.view].x > self.view.frame.size.width/2) {
            NSLog(@"DENIED TAP NEXT ON LAST PAGE");
            return NO;
        }
    }
    return YES;
}
Run Code Online (Sandbox Code Playgroud)