欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页

Swift ViewControllerTransitions

程序员文章站 2024-03-23 12:02:16
...

自定义Modally转场动画

准备

delegate转交给viewcontroller而不是系统

vc.transitioningDelegate = self

遵循协议

extension MainViewController:UIViewControllerTransitioningDelegate {
    
    //出现的函数,返回一个UIViewControllerAnimatedTransitioning的一个动画器,于是就新建一个
    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return PresentAnimator()
    }
    //退出的函数,同上返回一个动画器
    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return DismissAnimator()
    }
}

两个动画器

创建动画器

Swift ViewControllerTransitions

遵循两个协议

完成两个固定方法,一个设置动画经过时间,一个设置动画逻辑

class PresentAnimator:NSObject, UIViewControllerAnimatedTransitioning {

    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {}
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {}
}

完成动画器

PresentAnimator:

class PresentAnimator:NSObject, UIViewControllerAnimatedTransitioning {
    
    //动画的经过时间
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.3
    }
    
    //动画逻辑
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        
        guard
            //转场开始的vc
//            let fromVC = transitionContext.viewController(forKey: .from),
            //转场开始vc的根视图
            let fromView = transitionContext.view(forKey: .from),
            
            //转场结束的vc
//            let toVC = transitionContext.viewController(forKey: .to),
            //转场结束的vc的根视图
            let toView = transitionContext.view(forKey: .to)
        else{return}
        
        //类似于NavigationView
        let containerView = transitionContext.containerView
        //加入toView,UIKit会自动加入fromView
        containerView.addSubview(toView)
        
        toView.alpha = 0
        toView.transform = CGAffineTransform(translationX: containerView.frame.width, y: 0)
        
        UIView.animate(
            withDuration: transitionDuration(using: transitionContext),
            animations: {
                fromView.alpha = 0
                fromView.transform = CGAffineTransform(translationX: -containerView.frame.width, y: 0)
                toView.alpha = 1
                toView.transform = .identity
        }) { _ in
            fromView.transform = .identity
            toView.transform = .identity
            
            //UIKit调用这个方法来结束转场动画
            transitionContext.completeTransition(true)
        }
        
    }
    
//tcontainerView在动画结束的时候会自动移除fromView只剩下toView,一旦toView被dismiss就会黑屏,但是fromView的transform属性还在,所以在最后要给他还原
}


DismissAnimator:

class DismissAnimator: NSObject,UIViewControllerAnimatedTransitioning {
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.3
    }
    
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        
        guard
            let fromView = transitionContext.view(forKey: .from),
            let toView = transitionContext.view(forKey: .to)
        else{return}
        
        let containerView = transitionContext.containerView
        
        containerView.addSubview(toView)
        
        toView.alpha = 0
        toView.transform = CGAffineTransform(translationX: -containerView.frame.width, y: 0)
        
        UIView.animate(
            withDuration: transitionDuration(using: transitionContext),
            animations: {
                
                toView.alpha = 1
                toView.transform = .identity
                
                fromView.alpha = 0
                fromView.transform = CGAffineTransform(translationX: containerView.frame.width, y: 0)
        }) { _ in
            fromView.transform = .identity
            toView.transform = .identity
            
            transitionContext.completeTransition(true)
        }
        
    }
    

}


在转到的VC上设置dismiss

在ImageView上添加手势记得要加上
Swift ViewControllerTransitions

class DetailViewController: UIViewController {

    
    @IBOutlet weak var detailImageView: UIImageView!
    override func viewDidLoad() {
        super.viewDidLoad()
        
        //target表示这个手势在哪里运行,actiont传入函数的固定写法
        let tap = UITapGestureRecognizer(target: self, action: #selector(handleTap(tap:)))
        detailImageView.addGestureRecognizer(tap)
        // Do any additional setup after loading the view.
    }
    

    @objc func handleTap(tap:UITapGestureRecognizer) {
        dismiss(animated: true, completion: nil)
    }

}

相关标签: iOS 开发