Created
August 22, 2015 07:42
-
-
Save lynxerzhang/127c49a9bbf8a975e487 to your computer and use it in GitHub Desktop.
切换界面时自定义过度动画
This file contains hidden or 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
// | |
// TransitionManager.swift | |
// SwiftScreenMotionTips | |
// | |
//@see http://mathewsanders.com/animated-transitions-in-swift/ | |
import UIKit | |
import Darwin //contain pi's constant | |
class TransitionManager: NSObject, UIViewControllerAnimatedTransitioning, UIViewControllerTransitioningDelegate { | |
private var isReverse = false | |
private var pi = M_PI //import pi, alt + p create pi's character | |
/* from left to right and from right to left | |
func animateTransition(transitionContext: UIViewControllerContextTransitioning) { | |
let container = transitionContext.containerView() | |
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)! | |
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)! | |
let offScreenRight = CGAffineTransformMakeTranslation(container.frame.width, 0) | |
let offScreenLeft = CGAffineTransformMakeTranslation(-container.frame.width, 0) | |
if isReverse { | |
toView.transform = offScreenLeft | |
} | |
else { | |
toView.transform = offScreenRight | |
} | |
container.addSubview(toView) | |
container.addSubview(fromView) | |
let duration = self.transitionDuration(transitionContext) | |
UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.8, options: nil, animations: { | |
//[unowned self] in 由于isReverse为值复制类型,不需要进行内存管理 | |
if self.isReverse { | |
fromView.transform = offScreenRight | |
} | |
else { | |
fromView.transform = offScreenLeft | |
} | |
toView.transform = CGAffineTransformIdentity | |
}, completion: { finished in | |
transitionContext.completeTransition(true) | |
}) | |
} | |
*/ | |
func animateTransition(transitionContext: UIViewControllerContextTransitioning) { | |
let container = transitionContext.containerView() | |
let fromView = transitionContext.viewForKey(UITransitionContextFromViewKey)! | |
let toView = transitionContext.viewForKey(UITransitionContextToViewKey)! | |
let offScreenRotateIn = CGAffineTransformMakeRotation(CGFloat(-pi * 0.5)) | |
let offScreenRotateOut = CGAffineTransformMakeRotation(CGFloat(pi * 0.5)) | |
if isReverse { | |
toView.transform = offScreenRotateOut | |
} | |
else { | |
toView.transform = offScreenRotateIn | |
} | |
toView.layer.anchorPoint = CGPoint(x: 0, y: 0) | |
fromView.layer.anchorPoint = CGPoint(x: 0, y: 0) | |
toView.layer.position = CGPoint(x: 0, y: 0) | |
fromView.layer.position = CGPoint(x: 0, y: 0) | |
container.addSubview(toView) | |
container.addSubview(fromView) | |
let duration = self.transitionDuration(transitionContext) | |
UIView.animateWithDuration(duration, delay: 0.0, usingSpringWithDamping: 0.5, initialSpringVelocity: 0.8, options: nil, animations: { | |
if self.isReverse { | |
fromView.transform = offScreenRotateIn | |
} | |
else { | |
fromView.transform = offScreenRotateOut | |
} | |
toView.transform = CGAffineTransformIdentity | |
}, completion: { finished in | |
transitionContext.completeTransition(true) | |
}) | |
} | |
func transitionDuration(transitionContext: UIViewControllerContextTransitioning) -> NSTimeInterval { | |
return 0.5 | |
} | |
func animationControllerForPresentedController(presented: UIViewController, presentingController presenting: UIViewController, sourceController source: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
isReverse = false | |
return self | |
} | |
func animationControllerForDismissedController(dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? { | |
isReverse = true | |
return self | |
} | |
} | |
// | |
// ViewController.swift | |
// SwiftScreenMotionTips | |
// | |
import UIKit | |
class ViewController: UIViewController { | |
let transitionManager = TransitionManager() | |
override func viewDidLoad() { | |
super.viewDidLoad() | |
// Do any additional setup after loading the view, typically from a nib. | |
} | |
override func didReceiveMemoryWarning() { | |
super.didReceiveMemoryWarning() | |
// Dispose of any resources that can be recreated. | |
} | |
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) { | |
let toViewController = segue.destinationViewController as UIViewController | |
toViewController.transitioningDelegate = self.transitionManager | |
} | |
@IBAction func unwindToViewController(send: UIStoryboardSegue) { | |
} | |
override func preferredStatusBarStyle() -> UIStatusBarStyle { | |
return self.presentingViewController == nil ? UIStatusBarStyle.Default : UIStatusBarStyle.LightContent | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
1.在使用Closures时,需要注意是否会有内存回收问题。
在苹果swift文档的Automatic Reference Counting中
关于Defining a Capture的介绍Listhttps://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/AutomaticReferenceCounting.html#//apple_ref/doc/uid/TP40014097-CH20-ID48