Last active
October 2, 2018 14:26
-
-
Save nRewik/17ceb427b0fe21e8b4cb to your computer and use it in GitHub Desktop.
view controller transition from origin view to another view controller.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
//: Playground - noun: a place where people can play | |
import UIKit | |
import XCPlayground | |
extension UIView{ | |
var snapshot: UIImage{ | |
UIGraphicsBeginImageContextWithOptions(bounds.size, false, 0); | |
drawViewHierarchyInRect(bounds, afterScreenUpdates:true) | |
let image = UIGraphicsGetImageFromCurrentImageContext(); | |
UIGraphicsEndImageContext(); | |
return image | |
} | |
} | |
class TransformTransitioning: NSObject, UIViewControllerAnimatedTransitioning { | |
var originView: UIView? | |
var snapShot: UIImage! | |
var presenting = false | |
func animateTransition(transitionContext: UIViewControllerContextTransitioning) { | |
// view contontroller | |
guard let fromVC = transitionContext.viewControllerForKey(UITransitionContextFromViewControllerKey) else { return } | |
guard let toVC = transitionContext.viewControllerForKey(UITransitionContextToViewControllerKey) else { return } | |
// view | |
guard let containerView = transitionContext.containerView() else { return } | |
guard let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey) else { return } | |
guard let toView = transitionContext.viewForKey(UITransitionContextToViewKey) else { return } | |
guard let originView = originView else { return } | |
// frame | |
let containerFrame = containerView.frame | |
// take snapshot | |
if presenting{ | |
snapShot = originView.snapshot | |
} | |
let imageView = UIImageView(image: snapShot) | |
imageView.contentMode = .ScaleAspectFill | |
imageView.clipsToBounds = true | |
// calculate scale | |
let scaleX = originView.frame.width / containerFrame.width | |
let scaleY = originView.frame.height / containerFrame.height | |
let toViewStartTransform: CGAffineTransform | |
let toViewStartCenter: CGPoint | |
if presenting{ | |
toViewStartTransform = CGAffineTransformMakeScale(scaleX, scaleY) | |
toViewStartCenter = originView.center | |
}else{ | |
toViewStartTransform = CGAffineTransformIdentity | |
toViewStartCenter = containerView.center | |
} | |
imageView.alpha = 1.0 | |
imageView.frame = presenting ? originView.frame : containerView.frame | |
containerView.addSubview(imageView) | |
containerView.addSubview(toView) | |
// set frame | |
toView.frame = containerFrame | |
fromView.frame = containerFrame | |
if presenting{ | |
toView.transform = toViewStartTransform | |
toView.center = toViewStartCenter | |
containerView.bringSubviewToFront(imageView) | |
}else{ | |
containerView.bringSubviewToFront(imageView) | |
containerView.bringSubviewToFront(fromView) | |
} | |
let duration = transitionDuration(transitionContext) | |
UIView.animateWithDuration(duration, | |
animations: { | |
if self.presenting{ | |
toView.transform = CGAffineTransformIdentity | |
toView.center = containerView.center | |
imageView.frame = containerView.frame | |
imageView.alpha = 0.0 | |
}else{ | |
fromView.transform = CGAffineTransformMakeScale(scaleX, scaleY) | |
fromView.center = originView.center | |
fromView.alpha = 0.0 | |
imageView.frame = originView.frame | |
} | |
}, | |
completion:{ finish in | |
imageView.removeFromSuperview() | |
let success = !transitionContext.transitionWasCancelled() | |
if ((self.presenting && !success) || (!self.presenting && success)) { | |
toView.removeFromSuperview() | |
} | |
// reset transform | |
fromView.transform = CGAffineTransformIdentity | |
toView.transform = CGAffineTransformIdentity | |
transitionContext.completeTransition(success) | |
}) | |
} | |
func transitionDuration(transitionContext: UIViewControllerContextTransitioning?) -> NSTimeInterval { | |
return 0.6 | |
} | |
} | |
class ViewController: UIViewController { | |
let transformTransitioning = TransformTransitioning() | |
let originView = UIView() | |
override func viewDidLoad() { | |
view.backgroundColor = UIColor.darkGrayColor() | |
view.addSubview(originView) | |
transformTransitioning.originView = originView | |
transformTransitioning.presenting = true | |
transitioningDelegate = self | |
} | |
override func viewDidLayoutSubviews() { | |
super.viewDidLayoutSubviews() | |
originView.layer.cornerRadius = 10.0 | |
originView.backgroundColor = UIColor.whiteColor() | |
originView.frame.size = CGSize(width: view.frame.width/2.0, height: view.frame.height/2.0) | |
originView.center = view.center | |
originView.frame.origin.x -= 50 | |
} | |
} | |
extension ViewController: UIViewControllerTransitioningDelegate{ | |
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
transformTransitioning.presenting = true | |
return transformTransitioning | |
} | |
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
transformTransitioning.presenting = false | |
return transformTransitioning | |
} | |
} | |
let a = ViewController() | |
let b = UIViewController() | |
b.transitioningDelegate = a | |
b.view.backgroundColor = UIColor.yellowColor() | |
XCPlaygroundPage.currentPage.liveView = a | |
a.presentViewController(b, animated: true, completion: { | |
a.dismissViewControllerAnimated( true, completion: nil) | |
}) |
Author
nRewik
commented
Nov 4, 2015
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment