转场动画
以我们常用的present、push转场动画为例,这种过渡性视图展示效果被抽象成UIViewControllerAnimatedTransitioning协议
如下图,A present 到B则是调用系统默认的present协议,自定义转场动画则是实现UIViewControllerAnimatedTransitioning,重写协议中的动画对象animator
tip:当B.transitioningDelegate=nil时,B就会调用系统默认的present协议
自定义转场动画
咋们先看看要实现效果,图标有点丑,勿见怪hah
- 实现转场动画delegate
主要思路:
1、使用系统默认present转场操作
2、重写转场协议,设置动画时间、动画过渡效果
3、设置present to 对象的转场协议为 [步骤2 ]的协议
4、run~
协议实现的工具类如下
import UIKit
class MenuTransitionHepler: NSObject,UIViewControllerAnimatedTransitioning,UIViewControllerTransitioningDelegate {
private var isPresenting = false
//实现UIViewControllerAnimatedTransitioning代理方法
//过场动画持续时间
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.5
}
//过场动画实现
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
let container = transitionContext.containerView
let toVC=transitionContext.viewController(forKey: !self.isPresenting ? UITransitionContextViewControllerKey.from : UITransitionContextViewControllerKey.to)!
// let fromVC=transitionContext.viewController(forKey: !self.isPresenting ? UITransitionContextViewControllerKey.to : UITransitionContextViewControllerKey.from)!
// let fromView = fromVC.view
let toView = toVC.view
//设置动画初始位置
if self.isPresenting {
self.setOffAnimation(menuVC: toVC as! MenuVC)
}
container.addSubview(toView!)
let duration = self.transitionDuration(using: transitionContext)
UIView.animate(withDuration: duration, delay: 0, usingSpringWithDamping: 0.7, initialSpringVelocity: 0.8, options: UIViewAnimationOptions.curveLinear, animations: {
if self.isPresenting{
self.setOnAnimation(menuVC: toVC as! MenuVC)
}else{
self.setOffAnimation(menuVC: toVC as! MenuVC)
}
}, completion: {(finish:Bool) in
transitionContext.completeTransition(true)
})
}
func offCGAffineTransform(amount:CGFloat) -> CGAffineTransform {
return CGAffineTransform(translationX: amount, y: 0)
}
func setOffAnimation(menuVC:MenuVC){
menuVC.view.alpha = 0
// setup paramaters for 2D transitions for animations
let topRowOffset :CGFloat = 300
let middleRowOffset :CGFloat = 150
let bottomRowOffset :CGFloat = 50
menuVC.img_businessCar.transform = self.offCGAffineTransform(amount: -topRowOffset)
menuVC.l_businessCar.transform = self.offCGAffineTransform(amount: -topRowOffset)
menuVC.img_taxi.transform = self.offCGAffineTransform(amount: topRowOffset)
menuVC.l_taxi.transform = self.offCGAffineTransform(amount: topRowOffset)
menuVC.img_bus.transform = self.offCGAffineTransform(amount: -middleRowOffset)
menuVC.l_bus.transform = self.offCGAffineTransform(amount: -middleRowOffset)
menuVC.img_selfDrive.transform = self.offCGAffineTransform(amount: middleRowOffset)
menuVC.l_selfDrive.transform = self.offCGAffineTransform(amount: middleRowOffset)
menuVC.img_gasStation.transform = self.offCGAffineTransform(amount: -bottomRowOffset)
menuVC.l_gasStation.transform = self.offCGAffineTransform(amount: -bottomRowOffset)
menuVC.img_service.transform = self.offCGAffineTransform(amount: bottomRowOffset)
menuVC.l_service.transform = self.offCGAffineTransform(amount: bottomRowOffset)
}
func setOnAnimation(menuVC:MenuVC){
menuVC.view.alpha = 1
menuVC.img_businessCar.transform = CGAffineTransform.identity
menuVC.l_businessCar.transform = CGAffineTransform.identity
menuVC.img_taxi.transform = CGAffineTransform.identity
menuVC.l_taxi.transform = CGAffineTransform.identity
menuVC.img_bus.transform = CGAffineTransform.identity
menuVC.l_bus.transform = CGAffineTransform.identity
menuVC.img_selfDrive.transform = CGAffineTransform.identity
menuVC.l_selfDrive.transform = CGAffineTransform.identity
menuVC.img_gasStation.transform = CGAffineTransform.identity
menuVC.l_gasStation.transform = CGAffineTransform.identity
menuVC.img_service.transform = CGAffineTransform.identity
menuVC.l_service.transform = CGAffineTransform.identity
}
//UIViewControllerTransitioningDelegate代理方法
//presented
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.isPresenting=true
return self
}
//dismissed
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
self.isPresenting=false
return self
}
}
to VC里面设置present代理
let transitionHelper = MenuTransitionHepler()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.transitioningDelegate=self.transitionHelper
}
思考
1、后续可延伸交互式转场动画
2、交互式过场动画是否可作侧滑框架?
demo传送门,如果觉得有帮助还望给个star以示支持,thx~
https://github.com/marceChow/-