告诉UIPageViewController滚动时(用于图像的视差滚动)

时间:2013-04-28 21:41:52

标签: objective-c uiscrollview uiimage uipageviewcontroller

我试图产生类似于新雅虎天气应用程序中的效果。基本上,UIPageViewController中的每个页面都有一个背景图像,当滚动浏览页面视图时,图像的位置仅滚动大约一半的速度。我该怎么办?我以为我可以在UIPageViewController中使用某种委托方法来获取当前偏移量,然后像这样更新图像。唯一的问题是我无论如何都无法判断UIPageViewController是否正在滚动!有没有办法呢?谢谢!

8 个答案:

答案 0 :(得分:48)

for (UIView *view in self.pageViewController.view.subviews) {
    if ([view isKindOfClass:[UIScrollView class]]) {
         [(UIScrollView *)view setDelegate:self];
    }
} 

这使您可以访问所有标准滚动视图API方法。 这不是使用私有的Apple API。

我添加遍历子视图,100%找到UIPageViewController的内部滚动视图 警告: 小心使用 scrollview.contentOffset 。它会在控制器滚动到新页面时重置

如果您需要透视scrollview偏移跟踪和类似的东西,最好使用UICollectionViewController,其单元格大小为集合视图本身并启用分页。

答案 1 :(得分:15)

我会这样做:

<强>目标C

for (UIView *v in self.pageViewController.view.subviews) {
    if ([v isKindOfClass:[UIScrollView class]]) {
        ((UIScrollView *)v).delegate = self;
    }
}

并实施此协议

- (void)scrollViewDidScroll:(UIScrollView *)scrollView

<强>夫特

for view in self.pageViewController.view.subviews {
  if let scrollView = view as? UIScrollView {
    scrollView.delegate = self
  }
}

并实施此协议

func scrollViewDidScroll(scrollView: UIScrollView)

答案 2 :(得分:3)

我的猜测是不是一个UIPageViewController,而是一个分页的UIScrollView。 UIScrollView 为您提供了一个不断重复的委托方法,可以跟踪滚动发生时发生的事情。

或者,您可能能够访问UIPageViewController秘密使用的分页UIScrollView,但您可能会破坏某些内容,而且我不确定Apple会如何看待它。

答案 3 :(得分:3)

使用@Paul的片段 -

for (UIView *v in self.pageViewController.view.subviews) {
if ([v isKindOfClass:[UIScrollView class]]) {
    ((UIScrollView *)v).delegate = self;
}
}

实施此协议:-(void)scrollViewDidScroll:(UIScrollView *)scrollView

-(void)scrollViewDidScroll:(UIScrollView *)scrollView
{
CGPoint point = scrollView.contentOffset;

float percentComplete;
percentComplete = fabs(point.x - self.view.frame.size.width)/self.view.frame.size.width;
NSLog(@"percentComplete: %f", percentComplete);
}

这将为您提供滚动的完成百分比。快乐的编码!

答案 4 :(得分:2)

extension UIPageViewController {

    var scrollView: UIScrollView? {

        return view.subviews.filter { $0 is UIScrollView }.first as? UIScrollView
    }
}

使用:

pageController.scrollView?.delegate = self

答案 5 :(得分:1)

在Swift 3中你可以写得更短:

if let scrollView = self.pageViewController.view.subviews.first(where: { $0 is UIScrollView }) as? UIScrollView {
    scrollView.delegate = self
}

答案 6 :(得分:0)

你正在寻找的是视差滚动,你可以找到几个可以帮助你的库。

编辑:马特是对的,这不是答案,只是一个提示。无论如何,让我们完成它:

要为UIPageViewController后面的背景图像设置动画,您应该使用它提供的委托方法:

-[id<UIPageViewControllerDelegate> pageViewController:willTransitionToViewControllers:]
-[id<UIPageViewControllerDelegate> pageViewController:didFinishAnimating:previousViewControllers:transitionCompleted:]

使用这两种方法,您可以计算滚动的百分比(您应该将控制器存储在数组中以了解滚动到哪个控制器并获得百分比)

答案 7 :(得分:0)

您不应该更改页面视图控制器的滚动视图的委托:它可能会破坏其正常行为,并且/或者以后不再受支持。

相反,您可以:

  1. 向页面视图控制器的视图添加平移手势:

    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(panRecognized(gesture:)))
    view.addGestureRecognizer(panGesture)
    panGesture.delegate = self
    
  2. 添加新功能以了解视图如何滚动。

    @objc func panRecognized(gesture: UIPanGestureRecognizer) {
        // Do whatever you need with the gesture.translation(in: view)
    }
    
  3. 将您的ViewController声明为UIGestureRecognizerDelegate

  4. 实现此功能:

    func gestureRecognizer(_ gestureRecognizer: UIGestureRecognizer, shouldRecognizeSimultaneouslyWith otherGestureRecognizer: UIGestureRecognizer) -> Bool {
        return true
    }