在PageViewController上进行漂亮的过渡

我想在PageViewController中进行自定义转换:当用户移动到下一张幻灯片(滚动)时,背景图像会慢慢溶解到另一张图像中。

这样的效果有Apple Weather(除了有背景video)。

我做了什么:

  • 我用背景图像制作了UIViewContoller(我需要改变这个图像)。
  • 我在那个UIViewController中放置了ContainerView,ContainerView已经嵌入了PageViewController。 UIViewController – > ContainerView – > PageViewController

那时我卡住了,我已经使用共享背景图像(来自顶级UIViewController)工作PageViewController,但我不知道下一步该去哪里。

现在,我可以使用我的委托(主ViewContoller)捕获页面更改:

func pageChanged(currentPage: Int) {} 

和默认的委托方法(PageViewContoller)(我有2张幻灯片,不知道怎么做得更好):

 func pageViewController(pageViewController: UIPageViewController, didFinishAnimating finished: Bool, previousViewControllers: [AnyObject], transitionCompleted completed: Bool) { let prevController = previousViewControllers as [ContentViewController] if completed { if prevController[0].index == 0 { delegate.pageChanged(1) } else { delegate.pageChanged(2) } } } 

但它是即时function,我不能在这里慢慢动画依赖用户慢慢刷:)。

我完全赞同瓦西里。 您需要使用UICollectionView并使用self.collectionView.pagingEnabled = YES; 。 然后,您可以通过UIScrollViewDelegate完美地控制scrollview contentOffset。

 optional func scrollViewDidScroll(_ scrollView: UIScrollView) 

代码:

 func scrollViewDidScroll(scrollView: UIScrollView) { var currentX = scrollView.contentOffset.x var ratio = currentX / UIScreen.mainScreen().bounds.size.width var previousPageIndex = floor(ratio) var nextPageIndex = ceil(ratio) ratio = ratio - previousPageIndex } 

例如,如果ratio为0.33,则页面previousPageIndex和页面nextPageIndex之间的转换为33%。 您可以使用此值在UIImageView设置alpha值:

 func scrollViewDidScroll(scrollView: UIScrollView) { var currentX = scrollView.contentOffset.x var ratio = currentX / UIScreen.mainScreen().bounds.size.width var previousPageIndex = floor(ratio) var nextPageIndex = ceil(ratio) ratio = ratio - previousPageIndex fromImageView.alpha = 1.0 - ratio; toImageView.alpha = ratio; } 

PageViewController不允许您控制滚动本身。 过渡是一个离散的事件。 滑动手势也是一个离散事件,您可以使用它添加平滑效果。 平移手势可以帮助您,但代码将更复杂和肮脏。

接受的答案指示您使用UICollectionViewController而不是UIPageViewController以便您可以访问UIScrollView,设置它的委托并监视scrollViewDidScroll方法。

您可以像这样访问其滚动视图,而不是避免使用页面视图控制器:

  let scrollView = self.view.subviews.filter { $0 is UIScrollView }.first as? UIScrollView 

然后,您可以为scrollView设置委托,并享受对scrollViewDidScroll方法和其他方法的访问。 结合UIPageViewControllerDelegate协议实现UIScrollViewDelegate协议应该为您提供足够的状态信息来满足您的需求。