Helper classes to make basic view controller transitions easier
Add CustomTransition.swift to your project.
- Create an instance of
NavigationControllerDelegate
and set to the delegate property of anUINavigationController
. - Make the view controllers participating in the transition conforming to the
TransitionInfoProtocol
protocol. - There is no step three.
The TransitionInfoProtocol
defines two required and one optional methods:
// Return the views which shoud be animated in the transition
func viewsToAnimate() -> [UIView]
// Return a copy of the view which is passed in. The passed in view is one of the views to animate
func copyForView(subView: UIView) -> UIView
/* Optionally return the frames for the views which should be
animated. This is needed sometimes because for example
with custom container view contrllers the transitioning code
can't figure out where on screen the view is actually visible
when loaded. */
optional func frameForView(subView: UIView) -> CGRect
Let's say you want to animate a image view from the first view controller to the position of the second view controller (see the gif and the demo project). In the first view controller the protocol conformance could look like this:
import UIKit
class ViewController: UIViewController, TransitionInfoProtocol {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var label: UILabel!
func viewsToAnimate() -> [UIView] {
return [imageView, label]
}
func copyForView(subView: UIView) -> UIView {
if subView == imageView {
let imageViewCopy = UIImageView(image: imageView.image)
imageViewCopy.contentMode = imageView.contentMode
imageViewCopy.clipsToBounds = true
return imageViewCopy
} else if subView == label {
let labelCopy = UILabel()
labelCopy.text = label.text
labelCopy.font = label.font
labelCopy.backgroundColor = view.backgroundColor
return labelCopy
}
return UIView()
}
}
In the second view controller it could look like this:
import UIKit
class DetailViewController: UIViewController, TransitionInfoProtocol {
@IBOutlet weak var imageView: UIImageView!
@IBOutlet weak var label: UILabel!
func viewsToAnimate() -> [UIView] {
return [imageView, label]
}
func copyForView(subView: UIView) -> UIView {
if subView == imageView {
let imageViewCopy = UIImageView(image: imageView.image)
imageViewCopy.contentMode = imageView.contentMode
imageViewCopy.clipsToBounds = true
return imageViewCopy
} else if subView == label {
let labelCopy = UILabel()
labelCopy.text = label.text
labelCopy.font = label.font
labelCopy.backgroundColor = label.backgroundColor
return labelCopy
}
return UIView()
}
}
Dominik Hauser
MIT