Vasily
Vasily

Reputation: 3790

Making beautiful transitions at PageViewController

I want to make custom transition with in PageViewController: while user moves to next slide (scroll) then background image slowly dissolves into another image.

Such effect have Apple Weather (except there is background video).

What I've done:

At that point I'm stuck, i have working PageViewController with shared background image (from top UIViewController), but I have no idea where to go next.

Now I can catch page changing with my delegate (main ViewContoller):

func pageChanged(currentPage: Int) {}

And default delegate method (PageViewContoller) (I have 2 slides, don't know how to do it better):

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)
        }
    }
}

But it is instant function, I can't do here slowly animation in dependency of user slowly swipes :).

Upvotes: 1

Views: 1867

Answers (2)

JAB
JAB

Reputation: 3235

The accepted answer directs you to use a UICollectionViewController rather than a UIPageViewController so you can access the UIScrollView, set it's delegate and monitor the scrollViewDidScroll method.

Rather than avoiding using the page view controller, you can access its scroll view like this:

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

You can then set the delegate for the scrollView and enjoy access to the scrollViewDidScroll method and others. Implementing the UIScrollViewDelegate protocol in combination with the UIPageViewControllerDelegate protocol should provide you with enough state information to accomplish your needs.

Upvotes: 2

torcelly
torcelly

Reputation: 516

I totally agree with Vasily. You need to use a UICollectionView and use self.collectionView.pagingEnabled = YES;. Then you can control perfectly the scrollview contentOffset via UIScrollViewDelegate.

optional func scrollViewDidScroll(_ scrollView: UIScrollView)

The code:

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

}

For instance, if the ratio is 0.33, the transition is 33% between the page previousPageIndex and the page nextPageIndex. You can use this values for set your alpha values in your UIImageViews:

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;

}

The PageViewController doesn't allow you control scrolling itself. The transition is a discrete event here. The swipe gesture is a discrete event too and you can add a smooth effect with it. The pan gesture can help you but the code will be more complex and dirty.

Upvotes: -1

Related Questions