iOS swift轉(zhuǎn)場(chǎng)動(dòng)畫by TransitioningDelegate

轉(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

present的原理.png

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


轉(zhuǎn)場(chǎng)動(dòng)畫menu.gif
  • 實(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/-

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

友情鏈接更多精彩內(nèi)容