轉(zhuǎn)場動畫
以我們常用的present、push轉(zhuǎn)場動畫為例,這種過渡性視圖展示效果被抽象成UIViewControllerAnimatedTransitioning協(xié)議
如下圖敷燎,A present 到B則是調(diào)用系統(tǒng)默認(rèn)的present協(xié)議,自定義轉(zhuǎn)場動畫則是實現(xiàn)UIViewControllerAnimatedTransitioning燥狰,重寫協(xié)議中的動畫對象animator
tip:當(dāng)B.transitioningDelegate=nil時圈驼,B就會調(diào)用系統(tǒng)默認(rèn)的present協(xié)議
自定義轉(zhuǎn)場動畫
咋們先看看要實現(xiàn)效果,圖標(biāo)有點丑隐圾,勿見怪hah
- 實現(xiàn)轉(zhuǎn)場動畫delegate
主要思路:
1困食、使用系統(tǒng)默認(rèn)present轉(zhuǎn)場操作
2、重寫轉(zhuǎn)場協(xié)議翎承,設(shè)置動畫時間硕盹、動畫過渡效果
3、設(shè)置present to 對象的轉(zhuǎn)場協(xié)議為 [步驟2 ]的協(xié)議
4叨咖、run~
協(xié)議實現(xiàn)的工具類如下
import UIKit
class MenuTransitionHepler: NSObject,UIViewControllerAnimatedTransitioning,UIViewControllerTransitioningDelegate {
private var isPresenting = false
//實現(xiàn)UIViewControllerAnimatedTransitioning代理方法
//過場動畫持續(xù)時間
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.5
}
//過場動畫實現(xiàn)
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
//設(shè)置動畫初始位置
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里面設(shè)置present代理
let transitionHelper = MenuTransitionHepler()
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
self.transitioningDelegate=self.transitionHelper
}
思考
1瘩例、后續(xù)可延伸交互式轉(zhuǎn)場動畫
2、交互式過場動畫是否可作側(cè)滑框架甸各?
demo傳送門垛贤,如果覺得有幫助還望給個star以示支持,thx~
https://github.com/marceChow/-