【问题标题】:Intercepting the UIPanGestureRecognizer of a UIPageViewController breaks UIPageViewController behaviour拦截 UIPageViewController 的 UIPanGestureRecognizer 会破坏 UIPageViewController 行为
【发布时间】:2016-07-26 18:24:48
【问题描述】:

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

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。 p>

【问题讨论】:

  • 出于好奇,您为什么将 UIPanGestureRecognizer 与 UIPageViewController 一起使用?也许这是我的菜鸟问题,但是对于 UIPageViewController,有一些委托方法可以让您翻页或滑动到 UIPageViewController 内的下一个视图。
  • 因为我要求 PageViewController 内的视图控制器的子视图在用户交互时不会平移 pageviewcontroller。我正在尝试做的一个例子是苹果的天气应用程序。您可以在其中平移城市之间的 PageViewController,但也可以平移不平移父视图的子视图(您正在查看的城市的当天预测)。 UIPageViewController 委托方法中没有任何内容允许这样做。
  • 我明白了,我明白了。给我一秒钟的时间来回答。我要根据天气应用来回答,酷吗?
  • 那么为什么不向页面视图控制器添加一个额外的平移手势识别器,然后将您的手势识别器连接到页面视图控制器的手势识别器作为“必须失败”。自从我看到这个已经有一段时间了,但是有一个内置的机制,一个手势识别器在另一个失败之前不会触发。
  • 试过了,添加另一个需要 PageViewController 手势识别器失败的手势识别器的问题是手势没有“传递”到下面的视图,所以我无法与之交互带有手势的子视图。

标签: ios swift


【解决方案1】:

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 SmallView:UIView {
    //Since yours is not a ScrollView I changed to a view. You can add the Pan Gesture here. 
     var colors:[UIColor] = [UIColor.redColor(), UIColor.blueColor(), UIColor.blackColor()]

     convenience init(frame: CGRect, x:Int) {
         self.init()
         self.frame = frame
         self.backgroundColor = colors[x]

         setupGesture()
     }

     func setupGesture() {
         let pan = UIPanGestureRecognizer(target: self, action: #selector(SmallView.action))
     }
     func action(gesture:UIPanGestureRecognizer) {
         print("gesture = ", gesture)
     }
}

我的控制器

class MyController:UIViewController {

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

【讨论】:

  • 遗憾的是,这不起作用,应该处理手势而不影响 pageviewcontroller 的视图应该是 PageViewController 的 UIViewController 的子视图。它实际上不是滚动视图,就像示例天气应用程序中的情况一样,它是一个交互式图表。
  • 哪一个不是scrollView?您向我指出的“(您正在查看的城市的当天预测)不平移父视图”绝对是滚动视图。你可以反弹回来。就像一个滚动视图。尝试一下。然后查找 ScrollView 弹跳。
  • 最重要的是,ScrollView 绝对是 PageViewController 的子视图。这是 UIViewController 的子类。
  • 我想在 PageViewController 中使用的子视图不是滚动视图,我只需要当用户与之交互时,PageViewController 的 panviewgesture 不会触发,就像天气应用程序中的滚动视图不会触发父 PageViewController 的平移一样。但除此之外,有问题的视图应该是 PageViewController 内 UIViewController 的子视图,而不是直接像您的示例中那样的 PageViewController 的子视图。
  • 再一次,在您的情况下,scrollView 添加为 UIPageViewController 的直接子视图,而不是 UIPageViewController 的子视图(“页面”)的子视图。您的示例有效,因为滚动视图添加在 UIPageViewController 之上并阻止了手势。
猜你喜欢
  • 2016-04-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-20
  • 2021-12-22
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多