在 PageViewController 中进行漂亮的过渡

Making beautiful transitions at PageViewController

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

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

我做了什么:

那时我卡住了,我正在使用具有共享背景图像的 PageViewController(来自顶部 UIViewController),但我不知道下一步该去哪里。

现在我可以用我的委托(主 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)
        }
    }
}

但它是即时功能,我不能在这里做依赖于用户缓慢滑动的缓慢动画:)。

我完全同意瓦西里的观点。您需要使用 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 { [=10=] is UIScrollView }.first as? UIScrollView

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