Search code examples
iosswiftios8.1catransitionios9.1

Transition between two views works on iOS8 but not on iOS9


I've been trying for a few hours now to get the transition animation work between two views. The problem that appears all the time that when I get the code to work on ios8.1 it stops working on ios9.1 and the other way around. The problem is simply that the view I want to transition to disappears. I know that there were a lot of topics like that but none of the answers worked for me, it always helped for one version of ios and for the other one it would not work. I've read somewhere that the problem with the animations not working as they should is that I use AutoLayout and one of the solutions for that was to use layer transforms instead thats why I ended with a version of code that works on iOS8 but now doesn't work on iOS9... Here is the code that I use and works for iOS8

 class ChannelDetailsCollectionViewController: UICollectionViewController {
     @IBAction func backButtonPressed(sender: AnyObject) {
            self.navigationController?.popViewControllerAnimated(true)
        }
    }

class UIAnimatedNavigationControllerDelegate: NSObject, UINavigationControllerDelegate {
func navigationController(navigationController: UINavigationController, animationControllerForOperation operation: UINavigationControllerOperation, fromViewController fromVC: UIViewController, toViewController toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
    if operation == .Push {
        return SlideInAnimator()
    } else if operation == .Pop {
        return SlideInDismissAnimator()
    } else {
        return nil
    }
}


 func animateTransition(transitionContext: UIViewControllerContextTransitioning) {

    let containerView = transitionContext.containerView()!
    let toView = transitionContext.viewForKey(UITransitionContextToViewKey)!
    let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)!

    let duration = self.transitionDuration(transitionContext)

    containerView.addSubview(toView)

    let transition = CATransition()
    transition.startProgress = 0
    transition.endProgress = 1
    transition.speed  = 3.0
    transition.type = kCATransitionPush
    transition.subtype = kCATransitionFromLeft
    transition.duration = 1.0

    fromView.layer.addAnimation(transition, forKey:"transition")
    toView.layer.addAnimation(transition, forKey:"transition")

    fromView.hidden = true
    toView.hidden = false
    transitionContext.completeTransition(true)
}

And here is what worked for iOS9 In this version I saw that the view would dissapear in iOS8 when toView.transform = CGAffineTransformIdentity was called, I assume its because of autolayout. I've tried checking for nil views and adding them again but it still wouldn't work.

func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
    let container = transitionContext.containerView()
    let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
    let fromView = fromViewController!.view
    let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
    let toView = toViewController!.view

    toView.transform = getSlideTransform(toView, offset: -container!.frame.width)
    fromView.transform = getSlideTransform(toView, offset: 0.0)
    container!.addSubview(toView)
    container!.addSubview(fromView)


    let duration = self.transitionDuration(transitionContext)

    UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.8, options: [], animations: {

        toView.transform = CGAffineTransformIdentity
        fromView.transform = self.getSlideTransform(fromView, offset: fromView.frame.width+100)
        }, completion: { finished in

            transitionContext.completeTransition(true)
    })
}


private func getSlideTransform(view: UIView, offset: CGFloat) -> CGAffineTransform {

    let size = view.frame.size
    var offSetTransform = CGAffineTransformMakeTranslation(offset, 0)
    offSetTransform = CGAffineTransformScale(offSetTransform, 0.9, 0.9)

    return offSetTransform
}

Can somebody give me some tips what to try now? Because I'm out of ideas and as I said all the topics I've checked would solve a problem for one ver of iOS and crash the other one :/


Solution

  • So after few more hours of trying I got the code to work on both iOS8 and iOS9.

    I'm posting the working code for anyone who may have similar problem to mine and wasn't able to do anything about it

    func animateTransition(transitionContext: UIViewControllerContextTransitioning) {
        let container = transitionContext.containerView()
        let fromViewController = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey)
        let fromView = fromViewController!.view
        let toViewController = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey)
        let toView = toViewController!.view
    
        let duration = self.transitionDuration(transitionContext)
    
    toView.frame = transitionContext.initialFrameForViewController(toViewController!)
    fromView.frame = transitionContext.initialFrameForViewController(fromViewController!)
    
    toView.transform = getSlideTransform(toView, offset: -container!.frame.width)
    fromView.transform = getSlideTransform(toView, offset: 0.0)
    container!.addSubview(toView)
    
    
    UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.9, initialSpringVelocity: 0.8, options: [], animations: {
    fromView!.removeFromSuperview()
    toView.transform = CGAffineTransformIdentity
    fromView.transform = self.getSlideTransform(fromView, offset: fromView.frame.width)
    toView.frame = transitionContext.finalFrameForViewController(toViewController!)
    fromView.frame = transitionContext.finalFrameForViewController(fromViewController!)
    
        }, completion: { finished in
    
    transitionContext.completeTransition(true)
    })
    }
    

    Before animation I had to set the frame from the transitionContext using :initialFrameForViewController and during animations I had to set the final frames from transitionContext using :finalFrameForViewController. It prevented the view from disappearing, probably it finally got the right frame values.