我有一个导航控制器,用于推送包含UIPageViewController( PAGES )的视图控制器( PARENT )。现在我使用平移/滑动手势在页面视图控制器的子节点之间切换。但是,我无法再使用屏幕左边框中的滑动手势弹出 PARENT - 视图控制器,因为它被解释为 PAGES 中的手势。
当显示最左侧的视图控制器时,是否可以完成刷卡操作?
两个想法:
在pageViewController:viewControllerBeforeViewController
- >中返回nil不起作用。
将触摸区域限制为described here。
或者有更简单的方法吗?
答案 0 :(得分:15)
我和@smallwisdom的情况相同,但处理方式不同。
我有一个视图控制器A
,我可以将其推到导航控制器的堆栈之上。
此视图控制器A
包含一个水平滚动视图,从屏幕左侧一直延伸到右侧。
在这种情况下,当我想从导航控制器的堆栈中滑动屏幕以弹出视图控制器A
时,我最终做的就是滚动此水平滚动视图。
解决方案非常简单。
在我的视图控制器A
中,我有这样的代码:
_contentScrollView = [[UIScrollView alloc] init];
[self.view addSubview:_contentScrollView];
for (UIGestureRecognizer *gestureRecognizer in _contentScrollView.gestureRecognizers) {
[gestureRecognizer requireGestureRecognizerToFail:self.navigationController.interactivePopGestureRecognizer];
}
效果很好。这是做什么的? 它告诉scrollView的手势识别器,他们必须等待一些其他手势识别器是否能识别当前手势。
如果其他无法识别,则他们将不再需要等待,他们可以尝试识别当前的手势。
如果其他识别器成功并识别当前手势,则所有等待的手势识别器将自动失败。
他们必须等待的其他手势识别器被设置为导航控制器的interactivePopGestureRecognizer。他负责滑动到后退的姿势。
答案 1 :(得分:5)
我大多同意@ 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!);
}
}
}
答案 2 :(得分:1)
我的一个项目中有类似的问题,并使用以下方法。就我而言,它是iOS 7之前真正流行的左侧菜单之一。
我的解决方案是设置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的手势识别器。 (对于滚动视图样式页面视图控制器,gestureRecognizers属性不会返回它们。)这很烦人,但我发现访问它的唯一方法是遍历滚动视图&#39 ; s手势识别器并寻找平移手势。然后设置指向它的指针,并根据您当前是否显示最左侧的视图控制器来启用/禁用。
如果您想要保持正确的滑动,请将平移手势替换为您自己的子扫描平移手势识别器,可以根据平移手势的方向有条件地识别。
答案 3 :(得分:0)
首先,找到UIPageViewController' s scrollView
extension UIPageViewController {
var bk_scrollView: UIScrollView? {
if let v = view as? UIScrollView {
return v
}
// view.subviews 只有一个元素,其类型是 _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)
}
}
答案 4 :(得分:0)
@Lcsky的答案的快速版本:
if let interactivePopGesture = self.navigationController?.interactivePopGestureRecognizer, let pageViewController = self.swipeVC?.pageViewController {
let subView = pageViewController.view.subviews
for view in subView {
if let scrollView = view as? UIScrollView{
scrollView.panGestureRecognizer.require(toFail: interactivePopGesture)
}
}
}