vendredi 10 juin 2016

iOS Folding Animation as UIViewControllerContextTransitioning


I'm trying to find out the proper way of folding animation during the UIViewControllerContextTransitioning.

In this gif, you can see how much I achieved. But this is a concatination of 3 different 3d transformations: rotating, scaling and translating.

GIF link (Sorry, it's apparently too big to import as an image)

So as you can see the problem is that Rotating animation is slower than Translating animation and in result I'm getting an overlap side-effect in the middle of animation.

Any help would be appreciated!

Here's the code in animateTransition

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    guard let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) else { fatalError("toViewController") }
    guard let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) else { fatalError("fromViewController")  }
    let fromView = fromViewController.view
    let toView = toViewController.view

    print(UIScreen.mainScreen().bounds)

    let size = transitionContext.finalFrameForViewController(toViewController).size

    let containerView = transitionContext.containerView()

    toView.frame = transitionContext.finalFrameForViewController(toViewController)
    toView.frame = CGRectOffset(toView.frame, 0, -toView.frame.size.height)
    containerView?.addSubview(toView)

    var transform = CATransform3DIdentity;

    let upFromViewFold = createSnapshot(fromView, afterUpdates: false, rect: CGRect(origin: CGPointZero, size: CGSize(width: CGRectGetWidth(fromView.bounds), height: CGFloat(centerY))), up: true)
    upFromViewFold.layer.position = CGPoint(x: CGRectGetMidX(fromView.frame), y:  0)
    upFromViewFold.layer.transform = CATransform3DIdentity

    let bottomFromViewFold = createSnapshot(fromView, afterUpdates: false, rect: CGRect(x: 0, y: CGFloat(centerY), width: CGRectGetWidth(fromView.bounds), height: CGRectGetHeight(fromView.bounds) - CGFloat(centerY)), up: false)
    bottomFromViewFold.layer.position = CGPoint(x: CGRectGetMidX(fromView.frame), y: CGRectGetHeight(fromView.frame))
    bottomFromViewFold.layer.transform = CATransform3DIdentity

    //============================================================================================================================================================================================================
    let viewHeight = size.height
    let middle = viewHeight / 2

    let upToViewFold = createSnapshot(toView, afterUpdates: true, rect: CGRect(origin: CGPoint(x: 0, y: 0), size: CGSize(width: CGRectGetWidth(toView.bounds), height: middle)), up: true)

    upToViewFold.layer.position = CGPoint(x: CGRectGetMidX(toView.frame), y: CGFloat(centerY))
    transform.m34 = -1 / 1000 // (50 * upAddition)
    upToViewFold.layer.transform = CATransform3DConcat(CATransform3DMakeScale(1, 0.63, 1), CATransform3DRotate(transform, CGFloat(M_PI_2), -1.0, 0.0, 0.0))

    let bottomToViewFold = createSnapshot(toView, afterUpdates: true, rect: CGRect(x: 0, y: middle, width: CGRectGetWidth(toView.bounds), height: middle), up: false)

    bottomToViewFold.layer.position = CGPoint(x: size.width / 2, y: CGFloat(centerY))
    transform.m34 = -1 / 1000 // (50 * bottomAddition)
    bottomToViewFold.layer.transform = CATransform3DConcat(CATransform3DMakeScale(1, 0.63, 1), CATransform3DRotate(transform, CGFloat(M_PI_2), 1.0, 0.0, 0.0))

    fromView.frame = CGRectOffset(fromView.frame, 0, -fromView.frame.size.height)

    UIView.animateWithDuration(transitionDuration(transitionContext), delay: 0.0, options: UIViewAnimationOptions.CurveEaseIn, animations: {
        upFromViewFold.layer.transform = CATransform3DMakeTranslation(0, -upFromViewFold.frame.size.height, 0)//Rotate(transform, CGFloat(-M_PI_2 * 1.5), 1.0, 0.0, 0.0)
        bottomFromViewFold.layer.transform = CATransform3DMakeTranslation(0, bottomFromViewFold.frame.size.height, 0)//Rotate(transform, CGFloat(M_PI_2 * 1.5), 1.0, 0.0, 0.0)

        let upTransform = CATransform3DConcat(CATransform3DIdentity, CATransform3DMakeTranslation(0, -CGFloat(self.centerY), 0))
        //            upToViewFold.layer.position = CGPoint(x: CGRectGetMidX(toView.frame), y: 0)
        upToViewFold.layer.transform = upTransform

        let bottomTransform = CATransform3DConcat(CATransform3DIdentity, CATransform3DMakeTranslation(0, size.height - CGFloat(self.centerY), 0))
        //            bottomToViewFold.layer.position = CGPoint(x: CGRectGetMidX(toView.frame), y: size.height)
        bottomToViewFold.layer.transform = bottomTransform

    }) { (finished) in
        upFromViewFold.removeFromSuperview()
        bottomFromViewFold.removeFromSuperview()
        upToViewFold.removeFromSuperview()
        bottomToViewFold.removeFromSuperview()

        if transitionContext.transitionWasCancelled() {
            fromView.frame = containerView!.frame
        }
        else {
            toView.frame = containerView!.frame
            fromView.frame = containerView!.frame
        }

        transitionContext.completeTransition(!transitionContext.transitionWasCancelled())
    }
}

Aucun commentaire:

Enregistrer un commentaire