之前用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