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 :/
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.