轉(zhuǎn)場(chǎng)動(dòng)畫
以我們常用的present、push轉(zhuǎn)場(chǎng)動(dòng)畫為例,這種過渡性視圖展示效果被抽象成UIViewControllerAnimatedTransitioning協(xié)議
如下圖,A present 到B則是調(diào)用系統(tǒng)默認(rèn)的present協(xié)議,自定義轉(zhuǎn)場(chǎng)動(dòng)畫則是實(shí)現(xiàn)UIViewControllerAnimatedTransitioning,重寫協(xié)議中的動(dòng)畫對(duì)象animator

tip:當(dāng)B.transitioningDelegate=nil時(shí),B就會(huì)調(diào)用系統(tǒng)默認(rèn)的present協(xié)議
自定義轉(zhuǎn)場(chǎng)動(dòng)畫
咋們先看看要實(shí)現(xiàn)效果,圖標(biāo)有點(diǎn)丑,勿見怪hah

- 實(shí)現(xiàn)轉(zhuǎn)場(chǎng)動(dòng)畫delegate
主要思路:
1、使用系統(tǒng)默認(rèn)present轉(zhuǎn)場(chǎng)操作
2、重寫轉(zhuǎn)場(chǎng)協(xié)議,設(shè)置動(dòng)畫時(shí)間、動(dòng)畫過渡效果
3、設(shè)置present to 對(duì)象的轉(zhuǎn)場(chǎng)協(xié)議為 [步驟2 ]的協(xié)議
4、run~
協(xié)議實(shí)現(xiàn)的工具類如下
import UIKit
class MenuTransitionHepler: NSObject,UIViewControllerAnimatedTransitioning,UIViewControllerTransitioningDelegate {
private var isPresenting = false
//實(shí)現(xiàn)UIViewControllerAnimatedTransitioning代理方法
//過場(chǎng)動(dòng)畫持續(xù)時(shí)間
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0.5
}
//過場(chǎng)動(dòng)畫實(shí)現(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è)置動(dòng)畫初始位置
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)場(chǎng)動(dòng)畫
2、交互式過場(chǎng)動(dòng)畫是否可作側(cè)滑框架?
demo傳送門,如果覺得有幫助還望給個(gè)star以示支持,thx~
https://github.com/marceChow/-