将UIPageViewController滑动与iOS 7 UINavigationController反向滑动手势相结合

我有一个导航控制器,推一个包含UIPageViewController( PAGES )的视图控制器( PARENT )。 现在,我使用平移/轻扫手势在页面视图控制器的子项之间切换。 但是,我不能再使用屏幕左边缘的轻扫手势popupPARENT- view控制器,因为它被解释为PAGES中的手势。

当显示最左边的视图控制器时,是否可以实现轻扫?

两个想法:

  1. pageViewController:viewControllerBeforeViewController返回nil pageViewController:viewControllerBeforeViewController – >不起作用。

  2. 限制触摸区域,如此处所述 。

还是有更直接的方法?

我和@smallwisdom的情况一样,但处理方式不同。

我有一个视图控制器A ,我推动我的导航控制器的堆栈顶部。 该视图控制器A包含从屏幕左侧向右延伸的水平滚动视图。

在这种情况下,当我想要滑动屏幕从导航控制器的堆栈中popup视图控制器A ,我所做的只是滚动这个水平滚动视图。

解决scheme非常简单。

在我的视图控制器A里面,我有这样的代码:

 _contentScrollView = [[UIScrollView alloc] init]; [self.view addSubview:_contentScrollView]; for (UIGestureRecognizer *gestureRecognizer in _contentScrollView.gestureRecognizers) { [gestureRecognizer requireGestureRecognizerToFail:self.navigationController.interactivePopGestureRecognizer]; } 

它工作很好。 这是什么? 这是告诉scrollView的手势识别器,他们必须等待,看看其他手势识别器是否会识别当前的手势。

如果其他人不能识别,那么他们将不再需要等待,他们可以尝试识别当前的手势。

如果其他识别器成功识别当前手势,则所有等待的手势识别器将自动失败。

他们必须等待的其他手势识别器被设置为导航控制器的interactivePopGestureRecognizer。 他负责挥动手势。

我大多同意@ ancajic的答案。 当你将UIPageViewController的transitionStyle设置为'Scroll'时,我想提供一个额外的情况,其中你不会设置gestureRecognizers,解决方法是:

 if (self.navigationController?.interactivePopGestureRecognizer != nil) { for view in self.pageViewController!.view.subviews { if let scrollView = view as? UIScrollView { scrollView.panGestureRecognizer.requireGestureRecognizerToFail(self.navigationController!.interactivePopGestureRecognizer!); } } } 

我在其中一个项目中遇到类似问题,并使用以下方法。 就我而言,这是iOS 7之前非常受欢迎的左侧菜单之一。

我的解决scheme是设置UINavigationControllerDelegate,然后执行以下操作:

 - (void)navigationController:(UINavigationController *)navigationController didShowViewController:(UIViewController *)viewController animated:(BOOL)animated { // enable the interactive menu gesture only if at root, otherwise enable the pop gesture BOOL isRoot = (navigationController.viewControllers.firstObject == viewController); self.panGestureRecognizer.enabled = isRoot; navigationController.interactivePopGestureRecognizer.enabled = !self.panGestureRecognizer.enabled; } 

编辑:

另外,你需要在UIPageViewController的手势识别器中挂钩。 (它们不是由scrollRecognizers属性为一个滚动视图风格的页面视图控制器返回的。)这很烦人,但我发现访问它的唯一方法是遍历滚动视图的手势识别器,并寻找平移手势。 然后设置一个指针并根据当前是否显示最左边的视图控制器来启用/禁用。

如果要保持启用正确的滑动,则用您自己的可以根据平移手势的方向进行有条件识别的子类划分手势识别器replace平移手势。

首先,findUIPageViewController的scrollView

 extension UIPageViewController { var bk_scrollView: UIScrollView? { if let v = view as? UIScrollView { return v } // view.subviews 只有一个元素,其types是 _UIQueuingScrollView,是 UIScrollView 的子类// view.subviews have only one item of which the type is _UIQueuingScrollView, which is kind of UIScrollView's subclass. for v in view.subviews where v is UIScrollView { return v as? UIScrollView } return nil } } 

其次,设置gestureRecognizer的依赖。

 override func viewDidLoad() { super.viewDidLoad() if let ges = navigationController?.interactivePopGestureRecognizer { pageViewController.bk_scrollView?.panGestureRecognizer.require(toFail: ges) } }