31

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

4

8 回答 8

51
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大小与集合视图本身相同的单元格并启用分页。

于 2013-09-28T11:26:40.890 回答
16

我会这样做:

Objective-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)
于 2014-01-27T22:16:55.033 回答
3

我的猜测是它不是UIPageViewController,而是分页的 UIScrollView。UIScrollView确实为您提供了一个不断重复的委托方法,用于跟踪滚动发生时发生的情况。

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

于 2013-04-28T21:43:42.370 回答
3

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

if let scrollView = self.pageViewController.view.subviews.first(where: { $0 is UIScrollView }) as? UIScrollView {
    scrollView.delegate = self
}
于 2017-03-30T14:57:49.690 回答
3
extension UIPageViewController {

    var scrollView: UIScrollView? {

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

使用:

pageController.scrollView?.delegate = self
于 2017-11-16T11:52:06.220 回答
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);
}

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

于 2016-01-15T12:23:33.077 回答
1

您正在寻找的称为视差滚动,您可以找到几个可以帮助您的库。

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

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

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

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

于 2013-04-28T21:45:21.793 回答
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
    }
    
于 2020-11-09T13:52:47.610 回答