Swift基础之自定义PUSH和POP跳转动画
2016-12-09 11:21
399 查看
之前用OC代码写过PUSH和POP的转场动画,闲来无事,将其转换成Swift语言,希望对大家有帮助,转载请注明。。。。
如何实现PUSH和POP的转场动画?
首先,创建一个NSObject的类,分别用来实现PUSH和POP的动画效果
创建PUSH文件,实现扇形效果,代码如下:
需要注意的是,代理的实现方法要完整
var transitionContextT:UIViewControllerContextTransitioning?
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.8
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
self.transitionContextT = transitionContext
let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
//不添加的话,屏幕什么都没有
let containerView = transitionContext.containerView
containerView.addSubview((fromVC?.view)!)
containerView.addSubview((toVC?.view)!)
let originRect:CGRect = CGRect.init(x: 0, y: 0, width: 50, height: 50)
let maskStartPath = UIBezierPath.init(ovalIn: originRect)
//OC中CGRectInset(originRect, -2000, -2000)的Swift用法:originRect.insetBy(dx: -2000, dy: -2000)
let maskEndPath = UIBezierPath.init(ovalIn: originRect.insetBy(dx: -2000, dy: -2000))
//创建一个CAShapeLayer来负责展示圆形遮盖
let maskLayer = CAShapeLayer.init()
//将他的path指定为最终的path,来避免在动画完成后回弹
maskLayer.path = maskEndPath.cgPath
toVC?.view.layer.mask = maskLayer
let maskAnimation = CABasicAnimation.init(keyPath: "path")
maskAnimation.fromValue = maskStartPath.cgPath
maskAnimation.toValue = maskEndPath.cgPath
maskAnimation.duration = self.transitionDuration(using: transitionContext)
maskAnimation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
maskAnimation.fillMode = kCAFillModeForwards
maskAnimation.isRemovedOnCompletion = false
maskAnimation.delegate = self
maskLayer.add(maskAnimation, forKey: "path")
}
//MARK:----- CAAnimationDelegate
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
self.transitionContextT?.completeTransition(!(self.transitionContextT?.transitionWasCancelled)!)
//去除mask
self.transitionContextT?.viewController(forKey: UITransitionContextViewControllerKey.from)?.view.layer.mask = nil;
self.transitionContextT?.viewController(forKey: UITransitionContextViewControllerKey.to)?.view.layer.mask = nil;
}
然后,同理创建POP文件,实现弹跳的效果,代码如下:
var transitionContext:UIViewControllerContextTransitioning?
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.8
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
self.transitionContext = transitionContext
let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
//不添加的话,屏幕什么都没有
let containerView = transitionContext.containerView
containerView.addSubview((fromVC?.view)!)
containerView.addSubview((toVC?.view)!)
let durationN = self.transitionDuration(using: transitionContext)
let screenBounds:CGRect = UIScreen.main.bounds
let finalFrame:CGRect = transitionContext.finalFrame(for: toVC!)
//OC中CGRectOffset(finalFrame, 0, -screenBounds.size.height)的Swift的用法:finalFrame.offsetBy(dx: 0, dy: -screenBounds.size.height)
toVC?.view.frame = finalFrame.offsetBy(dx: 0, dy: -screenBounds.size.height)
//添加动画,有弹跳的效果,参数:usingSpringWithDamping的范围为0.0f到1.0f,数值越小「弹簧」的振动效果越明显,当设置为1.0时,就不弹跳
//toVC?.view.frame = finalFrame
//transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
UIView.animate(withDuration: durationN, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.0, options: UIViewAnimationOptions.curveLinear, animations: {() -> Void in
//print("11111111")
toVC?.view.frame = finalFrame
}, completion: ({(Bool) -> Void in
//print("22222222")
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}))
}
最后在需要使用跳转动画的地方添加self.navigationController?.delegate = self代理方法,并实现,代码如下:
//MARK:-----UINavigationControllerDelegate
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if operation==UINavigationControllerOperation.push {
return BHPopAnimation()
}
else if operation==UINavigationControllerOperation.pop{
return BHPushAnimation()
}
return nil
}
最后附上源代码,如果有问题请留言:https://github.com/hbblzjy/SwiftPushAndPopDemo
如何实现PUSH和POP的转场动画?
首先,创建一个NSObject的类,分别用来实现PUSH和POP的动画效果
创建PUSH文件,实现扇形效果,代码如下:
需要注意的是,代理的实现方法要完整
var transitionContextT:UIViewControllerContextTransitioning?
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.8
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
self.transitionContextT = transitionContext
let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
//不添加的话,屏幕什么都没有
let containerView = transitionContext.containerView
containerView.addSubview((fromVC?.view)!)
containerView.addSubview((toVC?.view)!)
let originRect:CGRect = CGRect.init(x: 0, y: 0, width: 50, height: 50)
let maskStartPath = UIBezierPath.init(ovalIn: originRect)
//OC中CGRectInset(originRect, -2000, -2000)的Swift用法:originRect.insetBy(dx: -2000, dy: -2000)
let maskEndPath = UIBezierPath.init(ovalIn: originRect.insetBy(dx: -2000, dy: -2000))
//创建一个CAShapeLayer来负责展示圆形遮盖
let maskLayer = CAShapeLayer.init()
//将他的path指定为最终的path,来避免在动画完成后回弹
maskLayer.path = maskEndPath.cgPath
toVC?.view.layer.mask = maskLayer
let maskAnimation = CABasicAnimation.init(keyPath: "path")
maskAnimation.fromValue = maskStartPath.cgPath
maskAnimation.toValue = maskEndPath.cgPath
maskAnimation.duration = self.transitionDuration(using: transitionContext)
maskAnimation.timingFunction = CAMediaTimingFunction.init(name: kCAMediaTimingFunctionEaseInEaseOut)
maskAnimation.fillMode = kCAFillModeForwards
maskAnimation.isRemovedOnCompletion = false
maskAnimation.delegate = self
maskLayer.add(maskAnimation, forKey: "path")
}
//MARK:----- CAAnimationDelegate
func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
self.transitionContextT?.completeTransition(!(self.transitionContextT?.transitionWasCancelled)!)
//去除mask
self.transitionContextT?.viewController(forKey: UITransitionContextViewControllerKey.from)?.view.layer.mask = nil;
self.transitionContextT?.viewController(forKey: UITransitionContextViewControllerKey.to)?.view.layer.mask = nil;
}
然后,同理创建POP文件,实现弹跳的效果,代码如下:
var transitionContext:UIViewControllerContextTransitioning?
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.8
}
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
self.transitionContext = transitionContext
let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
//不添加的话,屏幕什么都没有
let containerView = transitionContext.containerView
containerView.addSubview((fromVC?.view)!)
containerView.addSubview((toVC?.view)!)
let durationN = self.transitionDuration(using: transitionContext)
let screenBounds:CGRect = UIScreen.main.bounds
let finalFrame:CGRect = transitionContext.finalFrame(for: toVC!)
//OC中CGRectOffset(finalFrame, 0, -screenBounds.size.height)的Swift的用法:finalFrame.offsetBy(dx: 0, dy: -screenBounds.size.height)
toVC?.view.frame = finalFrame.offsetBy(dx: 0, dy: -screenBounds.size.height)
//添加动画,有弹跳的效果,参数:usingSpringWithDamping的范围为0.0f到1.0f,数值越小「弹簧」的振动效果越明显,当设置为1.0时,就不弹跳
//toVC?.view.frame = finalFrame
//transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
UIView.animate(withDuration: durationN, delay: 0.0, usingSpringWithDamping: 0.6, initialSpringVelocity: 0.0, options: UIViewAnimationOptions.curveLinear, animations: {() -> Void in
//print("11111111")
toVC?.view.frame = finalFrame
}, completion: ({(Bool) -> Void in
//print("22222222")
transitionContext.completeTransition(!transitionContext.transitionWasCancelled)
}))
}
最后在需要使用跳转动画的地方添加self.navigationController?.delegate = self代理方法,并实现,代码如下:
//MARK:-----UINavigationControllerDelegate
func navigationController(_ navigationController: UINavigationController, animationControllerFor operation: UINavigationControllerOperation, from fromVC: UIViewController, to toVC: UIViewController) -> UIViewControllerAnimatedTransitioning? {
if operation==UINavigationControllerOperation.push {
return BHPopAnimation()
}
else if operation==UINavigationControllerOperation.pop{
return BHPushAnimation()
}
return nil
}
最后附上源代码,如果有问题请留言:https://github.com/hbblzjy/SwiftPushAndPopDemo
相关文章推荐
- Swift基础之自定义PUSH和POP跳转动画
- 自定义PUSH POP跳转动画
- swift详解之二十七------------自定义UINavigationController的push和pop动画
- 最实用的基础动画push pop新界面的时候
- IOS 自定义push和pop动画
- 【iOS学习笔记 15-11-06】简单自定义navigationcontroller push和pop动画效果
- 自定义控制器的转场动画(Push、Pop)
- 自定义UINavigationController的push和pop切换界面动画
- 自定义UINavigationController push和pop动画
- UINavigationController自定义,push和pop动画
- 控制器转场动画自定义(1):push/pop的实现
- NavigationController 自定义pop和push动画
- Swift-->ViewController跳转,转场以及自定义动画
- OC UINavigationController push pop自定义动画
- 自定义Push和Pop过渡动画
- iOS 自定义转场动画 persent&dismiss , push&pop
- 自定义控制器的转场动画(Push、Pop)
- 自定义NavigationController 的Push 和 Pop过渡动画
- 第六十五篇、OC_iOS7 自定义转场动画push pop