Ios 拦截UIPageViewController的UIPangEstureRecognitor会破坏UIPageViewController的行为

Ios 拦截UIPageViewController的UIPangEstureRecognitor会破坏UIPageViewController的行为,ios,swift,Ios,Swift,我试图将UIPageViewController的UIPangestureRecognitor分配给不同的(自定义)视图,以便用于页面切换的平移手势仅适用于屏幕的特定区域。代码基本上如下所示: let testView = UIView(frame: CGRect(x: 0, y:self.view.frame.height/2, width: 320, height: self.view.frame.height/2)) self.view.addSubview(testView) for g

我试图将UIPageViewController的UIPangestureRecognitor分配给不同的(自定义)视图,以便用于页面切换的平移手势仅适用于屏幕的特定区域。代码基本上如下所示:

let testView = UIView(frame: CGRect(x: 0, y:self.view.frame.height/2, width: 320, height: self.view.frame.height/2))
self.view.addSubview(testView)
for gr in self.pageViewController!.view.subviews[0].gestureRecognizers! {            
        if gr.isKindOfClass(UIPanGestureRecognizer) {
            testView.addGestureRecognizer(gr)
        }
}
问题在于,在进行平移时,“下一个”视图控制器不会立即可见,在第一次平移时,当前视图控制器(第一个)似乎是PageViewController中的唯一视图控制器,只有在结束平移并进行第二次平移后,下一个视图控制器才会出现

请注意,在不将UIPanGesture指定给其他视图的情况下,PageViewController会按预期工作,并且自第一次平移后下一个视图控制器可见

我为什么要这样做?我需要在PageViewController内的视图控制器中添加一个子视图,当用户在其上做手势时,该子视图不会“平移”PageViewController。

class PageController:UIPageViewController {

    let viewControllers:[UIViewController] = [MyController(), MyController(), MyController()]

    override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : AnyObject]?) {
super.init(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: options)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        if let firstVC = controllers.first {
            setViewControllers([firstVC], direction.Forward, animated: true, completion:nil)
        }    
    } 

    func pageViewController(pageViewController: UIPageViewController,
viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
            return nil
        }

        let previousIndex = viewControllerIndex - 1

        guard previousIndex >= 0 else {
            return nil
        }

        guard orderedViewControllers.count > previousIndex else {
            return nil
        }

        return orderedViewControllers[previousIndex]
     }

    func pageViewController(pageViewController: UIPageViewController,
viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
            return nil
        }

        let nextIndex = viewControllerIndex + 1
        let orderedViewControllersCount = orderedViewControllers.count

        guard orderedViewControllersCount != nextIndex else {
            return nil
        }  

        guard orderedViewControllersCount > nextIndex else {
            return nil
        }

        return orderedViewControllers[nextIndex]
    }

 }
class MyController:UIViewController {

    override func viewDidLoad() {
        ......
        let view = SmallView(frame:CGRect(//some frame here))
        self.view.addSubview(view)
}
看法

霉菌控制者

class PageController:UIPageViewController {

    let viewControllers:[UIViewController] = [MyController(), MyController(), MyController()]

    override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : AnyObject]?) {
super.init(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: options)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        if let firstVC = controllers.first {
            setViewControllers([firstVC], direction.Forward, animated: true, completion:nil)
        }    
    } 

    func pageViewController(pageViewController: UIPageViewController,
viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
            return nil
        }

        let previousIndex = viewControllerIndex - 1

        guard previousIndex >= 0 else {
            return nil
        }

        guard orderedViewControllers.count > previousIndex else {
            return nil
        }

        return orderedViewControllers[previousIndex]
     }

    func pageViewController(pageViewController: UIPageViewController,
viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
            return nil
        }

        let nextIndex = viewControllerIndex + 1
        let orderedViewControllersCount = orderedViewControllers.count

        guard orderedViewControllersCount != nextIndex else {
            return nil
        }  

        guard orderedViewControllersCount > nextIndex else {
            return nil
        }

        return orderedViewControllers[nextIndex]
    }

 }
class MyController:UIViewController {

    override func viewDidLoad() {
        ......
        let view = SmallView(frame:CGRect(//some frame here))
        self.view.addSubview(view)
}
UIPageViewController

class PageController:UIPageViewController {

    let viewControllers:[UIViewController] = [MyController(), MyController(), MyController()]

    override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : AnyObject]?) {
super.init(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: options)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        if let firstVC = controllers.first {
            setViewControllers([firstVC], direction.Forward, animated: true, completion:nil)
        }    
    } 

    func pageViewController(pageViewController: UIPageViewController,
viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
            return nil
        }

        let previousIndex = viewControllerIndex - 1

        guard previousIndex >= 0 else {
            return nil
        }

        guard orderedViewControllers.count > previousIndex else {
            return nil
        }

        return orderedViewControllers[previousIndex]
     }

    func pageViewController(pageViewController: UIPageViewController,
viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
            return nil
        }

        let nextIndex = viewControllerIndex + 1
        let orderedViewControllersCount = orderedViewControllers.count

        guard orderedViewControllersCount != nextIndex else {
            return nil
        }  

        guard orderedViewControllersCount > nextIndex else {
            return nil
        }

        return orderedViewControllers[nextIndex]
    }

 }
class MyController:UIViewController {

    override func viewDidLoad() {
        ......
        let view = SmallView(frame:CGRect(//some frame here))
        self.view.addSubview(view)
}
看法

霉菌控制者

class PageController:UIPageViewController {

    let viewControllers:[UIViewController] = [MyController(), MyController(), MyController()]

    override init(transitionStyle style: UIPageViewControllerTransitionStyle, navigationOrientation: UIPageViewControllerNavigationOrientation, options: [String : AnyObject]?) {
super.init(transitionStyle: .Scroll, navigationOrientation: .Horizontal, options: options)
    }

    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        if let firstVC = controllers.first {
            setViewControllers([firstVC], direction.Forward, animated: true, completion:nil)
        }    
    } 

    func pageViewController(pageViewController: UIPageViewController,
viewControllerBeforeViewController viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
            return nil
        }

        let previousIndex = viewControllerIndex - 1

        guard previousIndex >= 0 else {
            return nil
        }

        guard orderedViewControllers.count > previousIndex else {
            return nil
        }

        return orderedViewControllers[previousIndex]
     }

    func pageViewController(pageViewController: UIPageViewController,
viewControllerAfterViewController viewController: UIViewController) -> UIViewController? {
        guard let viewControllerIndex = orderedViewControllers.indexOf(viewController) else {
            return nil
        }

        let nextIndex = viewControllerIndex + 1
        let orderedViewControllersCount = orderedViewControllers.count

        guard orderedViewControllersCount != nextIndex else {
            return nil
        }  

        guard orderedViewControllersCount > nextIndex else {
            return nil
        }

        return orderedViewControllers[nextIndex]
    }

 }
class MyController:UIViewController {

    override func viewDidLoad() {
        ......
        let view = SmallView(frame:CGRect(//some frame here))
        self.view.addSubview(view)
}


出于好奇,您为什么要将UIPangestureRecognitor与UIPageViewController一起使用?也许这是我这边的一个noob问题,但是对于UIPageViewController,有一些委托方法允许您在UIPageViewController内翻页或滑动到下一个视图。因为我要求PageViewController内的视图控制器的子视图在用户交互时不平移PageViewController。我正在尝试做的一个例子就是苹果的天气应用程序。您可以在城市之间平移PageViewController,但也可以平移不平移父视图的子视图(您正在查看的城市的当天预测)。UIPageViewController委托方法中没有允许这样做的内容。我明白了,我明白了。给我一点时间回答。我将根据天气应用程序回答,酷?那么,为什么不在页面视图控制器上添加一个额外的平移手势识别器,然后将您的手势识别器连接到页面视图控制器的手势识别器,作为“必须失败”的一个选项。我已经有一段时间没有看到这一点了,但有一种内置机制,在另一个手势识别器出现故障之前,手势识别器不会启动。尝试过这种方法后,添加另一个手势识别器会导致PageViewController手势识别器出现故障,问题在于手势不会“传递”到下面的视图,因此,我无法用手势与子视图交互。出于好奇,为什么要使用带UIPageViewController的UIPangestureRecognitor?也许这是我这边的一个noob问题,但是对于UIPageViewController,有一些委托方法允许您在UIPageViewController内翻页或滑动到下一个视图。因为我要求PageViewController内的视图控制器的子视图在用户交互时不平移PageViewController。我正在尝试做的一个例子就是苹果的天气应用程序。您可以在城市之间平移PageViewController,但也可以平移不平移父视图的子视图(您正在查看的城市的当天预测)。UIPageViewController委托方法中没有允许这样做的内容。我明白了,我明白了。给我一点时间回答。我将根据天气应用程序回答,酷?那么,为什么不在页面视图控制器上添加一个额外的平移手势识别器,然后将您的手势识别器连接到页面视图控制器的手势识别器,作为“必须失败”的一个选项。我已经有一段时间没有看到这一点了,但有一种内置机制,在另一个手势识别器出现故障之前,手势识别器不会启动。尝试过这种方法后,添加另一个手势识别器会导致PageViewController手势识别器出现故障,问题在于手势不会“传递”到下面的视图,因此,我无法使用手势与子视图交互。遗憾的是,这不起作用,在不影响pageviewcontroller的情况下,应该处理手势的视图应该是pageviewcontroller的UIViewController的子视图。它实际上不是一个滚动视图,就像示例天气应用程序中的情况一样,它是一个交互式图表。哪个1不是滚动视图?您向我指出的“(您正在查看的城市的当天预测)没有平移父视图”绝对是滚动视图。你可以把它弹回来。就像滚动视图一样。试试看。然后查找ScrollView bounce。除此之外,ScrollView肯定是PageViewController的子视图。它是UIViewController的一个子类。我想在PageViewController中使用的子视图不是scrollview,我只需要当用户与它交互时,PageViewController的PanView手势不会触发,就像天气应用程序中的scrollview不会触发父PageViewController的pan。但除此之外,所讨论的视图应该是PageViewController内部UIViewController的子视图,而不是像您的示例中那样直接作为PageViewController的子视图。同样,您案例中的scrollView被添加为UIPageViewController的直接子视图,相反,它应该是UIPageViewController的子视图(“页面”)。您的示例之所以有效,是因为scrollview添加在UIPageViewController的顶部并阻止了手势。遗憾的是,这不起作用,应该在不影响pageviewcontroller的情况下处理手势的视图应该是pageviewcontroller的UIViewController的子视图。它实际上不是一个滚动视图,就像示例天气应用程序中的情况一样,它是一个交互式图表。哪个1不是滚动视图?您向我指出的“(您正在查看的城市的当天预测)没有平移父视图”绝对是滚动视图。你可以把它弹回来。就像滚动视图一样。试试看。然后向上看ScrollView bounce最重要的是,