UIPageViewController在iOS 6中不返回Gesture Recognizers

bjt*_*tus 34 iphone objective-c uikit uipageviewcontroller

我正在尝试为UIPageViewController禁用平移手势识别器.

在iOS 5上,我可以遍历它们并禁用它们.

for (UIGestureRecognizer* recognizer in self.pageViewController.gestureRecognizers) {
    if ([recognizer isKindOfClass:[UIPanGestureRecognizer class]]) {
        recognizer.enabled = NO;
    }
}
Run Code Online (Sandbox Code Playgroud)

在iOS 6上使用UIPageViewControllerTransitionStyleScroll,页面视图控制器没有返回手势识别器.

澄清

这可归结为:

当UIPageViewController的过渡样式设置为滚动时,self.pageViewController.gestureRecognizers = 0,因此我无法访问手势识别器.

有什么方法可以解决这个问题吗?因为卷曲过渡工作正常,我不认为我做错了什么.

lea*_*nne 31

在UIPageViewController.h中找到了这个:

//仅当过渡样式为"UIPageViewControllerTransitionStylePageCurl"时才填充. @property(nonatomic,readonly)NSArray*gestureRecognizers;

所以,不是一个错误 - 通过设计,当设置滚动样式时,pageViewController不会获得手势识别器.

  • @leanne:+1 发现这一点。问题出现了:头文件或参考文档是“真正的”参考吗?苹果至少可以将该通知添加到其文档中,以免人们头疼... (2认同)

小智 27

您始终可以尝试在页面视图控制器的子视图上禁用用户交互:

for (UIScrollView *view in self.pageViewController.view.subviews) {
    if ([view isKindOfClass:[UIScrollView class]]) {
        view.scrollEnabled = NO;
    }
}
Run Code Online (Sandbox Code Playgroud)


ser*_*gio 26

这种行为在雷达中存在一个错误.所以,我敢打赌,在Apple修复之前,没有机会解决这个问题.

我想到的一个解决方法是在您的顶部放置一个透明的子视图,UIPageViewController并添加一个UIPanGestureRecognizer拦截这种手势而不是进一步前进.您可以在需要禁用手势时启用此视图/识别器.

我尝试使用Pan和Tap手势识别器的组合,它的工作原理.

这是我的测试代码:

- (void)viewDidLoad {
  [super viewDidLoad];

   UIPanGestureRecognizer* g1 = [[[UIPanGestureRecognizer alloc] initWithTarget:self
                                                                      action:@selector(g1Pan:)] autorelease];
  [self.view addGestureRecognizer:g1];

  UITapGestureRecognizer* s1 = [[[UITapGestureRecognizer alloc] initWithTarget:self
                                                                      action:@selector(g1Tap:)] autorelease];

  [self.view addGestureRecognizer:s1];

  UIView* anotherView = [[[UIView alloc]initWithFrame:self.view.bounds] autorelease];
  [self.view addSubview:anotherView];

  UIPanGestureRecognizer* g2 = [[[UIPanGestureRecognizer alloc] initWithTarget:self
                                                                      action:@selector(g2Pan:)] autorelease];
  [anotherView addGestureRecognizer:g2];

}
Run Code Online (Sandbox Code Playgroud)

g2启用时,它会阻止g1被识别.另一方面,它不会阻止s1被识别.

我知道这是黑客,但面对一个看似错误UIPageViewController(至少,实际行为与参考状态明显不同),我看不出更好的解决方案.


3rd*_*Bot 18

根据UIPageViewController头文件,当数据源为nil时,禁用手势驱动导航.

因此,如果要禁用滑动,请将datasource设置为nil,然后在要启用滑动时,重置数据源.

// turns off paging
pageViewController.datasource = nil

// turns on paging
pageViewController.datasource = self;
Run Code Online (Sandbox Code Playgroud)

  • 这绝对是最优雅的解决方案,在Apple的官方API文档中最少捣乱并利用所陈述的行为. (2认同)

小智 8

您可以从UIPageViewController通过UIScrollview访问UIPanGestureRecognizer.

for (UIView *view in self.pageController.view.subviews) {
    if ([view isKindOfClass:[UIScrollView class]])
    {
        UIScrollView *scrollView = (UIScrollView *)view;

        UIPanGestureRecognizer* panGestureRecognizer = scrollView.panGestureRecognizer;
        [panGestureRecognizer addTarget:self action:@selector(move:)];
    }
}
Run Code Online (Sandbox Code Playgroud)