當(dāng)我們的視圖控制器調(diào)用present(_:animated:completion:)方法時,會退出一個新的控制器,此時,默認(rèn)的動畫是從下往上出現(xiàn)的。那么,假如有時候,需求是從別的方向出現(xiàn)呢?我們就來研究研究應(yīng)該怎么做。
1.準(zhǔn)備工作
1.要做的準(zhǔn)備工作很簡單,首先,新建一個轉(zhuǎn)場動畫類,該類是NSObject的子類,同時,要遵循UIViewControllerAnimatedTransitioning協(xié)議:
class PopAnimator: NSObject, UIViewControllerAnimatedTransitioning {
}
2.實(shí)現(xiàn)UIViewControllerAnimatedTransitioning協(xié)議的兩個方法:
//轉(zhuǎn)場時間
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return 0
}
//動畫代碼
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
}
transitionDuration方法,返回的是轉(zhuǎn)場動畫消耗的時間。
animateTransition方法,內(nèi)部是具體的轉(zhuǎn)場動畫的實(shí)現(xiàn)。
3.在要使用自定義轉(zhuǎn)場動畫的VC中,給該VC添加一個擴(kuò)展,遵循UIViewControllerTransitioningDelegate協(xié)議:
extension ViewController: UIViewControllerTransitioningDelegate {
}
4.在使用present()方法,退出新視圖的地方,添加代理
let vc = UIViewController()
vc.transitioningDelegate = self
self.present(vc, animated: true, completion: nil)
5.在擴(kuò)展中,添加如下方法
extension ViewController: UIViewControllerTransitioningDelegate {
//出現(xiàn)時,調(diào)用該轉(zhuǎn)場
func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
//返回轉(zhuǎn)場動畫
return PopAnimator()
}
//消失時,使用默認(rèn)
func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
return nil;
}
}
至此,準(zhǔn)備工作已經(jīng)做完,接下來就是動畫的實(shí)現(xiàn)部分。
2.在PopAnimator類中,添加轉(zhuǎn)場動畫的實(shí)現(xiàn)
在PopAnimator中,先把基礎(chǔ)給打好,如下
class PopAnimator: NSObject, UIViewControllerAnimatedTransitioning {
//時間
let duration = 1.0
//用來表示是打開還是關(guān)閉
var show = true
//起始frame
var originFrame = CGRect.zero
//轉(zhuǎn)場時間
func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
return duration
}
//動畫代碼
func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
}
}
duration屬性,用于決定動畫時間。
show用于判斷是彈出還是消失。
originFrame初始的位置
接下來實(shí)現(xiàn)淡入的動畫效果:
//容器view
let containerView = transitionContext.containerView
//新view
let toView = transitionContext.view(forKey: .to)
containerView.addSubview(toView!)
toView?.alpha = 0
UIView.animate(withDuration: duration,
animations: {
toView?.alpha = 1
}) { _ in
transitionContext.completeTransition(true)
}
containerView,容器view。一切動畫都是在該容器內(nèi)進(jìn)行的。
toView,將要呈現(xiàn)的view。