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

【Swift】模态视图的动画展示

程序员文章站 2022-03-17 10:39:02
...

1、业务需求:点击按钮,自定义一个模态动画,动画大概,把上个界面一分为二,从中间分离然后显示模态出来的界面

import UIKit
// 枚举:present、dismiss的动画区分
enum CNPresentOneTransitionType {
    case Present // 管理present动画
    case Dismiss // 管理dismiss动画

}
class CNPresnetOneTransition: NSObject,UIViewControllerAnimatedTransitioning {
    var typeT : CNPresentOneTransitionType!
    init(transitionType:CNPresentOneTransitionType) {
        super.init()
        typeT = transitionType
    }
    // 动画时间
    func transitionDuration(using transitionContext: UIViewControllerContextTransitioning?) -> TimeInterval {
        return 0.25
    }
    // 做动画需要的前后两个视图
    func animateTransition(using transitionContext: UIViewControllerContextTransitioning) {
        switch typeT! {
        case CNPresentOneTransitionType.Present:
            presentAnimation(transitionContext: transitionContext)
        case CNPresentOneTransitionType.Dismiss:
            dismissAnimation(transitionContext: transitionContext)
        default:
            break
        }
    }

    // 实现present动画逻辑代码
    func presentAnimation(transitionContext : UIViewControllerContextTransitioning){
        let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)

        if fromVC!.isKind(of: UINavigationController.self){
            print("sssss")
        }

        let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to) as! UINavigationController
        if toVC.isKind(of: UINavigationController.self){
            print("hhhh")
        }
        let contentView = transitionContext.containerView

        let screenWidth = UIScreen.main.bounds.size.width
        let screenHeight = UIScreen.main.bounds.size.height

        var rect0 : CGRect!
        var rect1 : CGRect!

        rect0 = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight/2)
        rect1 = CGRect(x: 0, y: screenHeight/2, width: screenWidth, height: screenWidth)


        let image0 = imageFromView(view:(fromVC?.view)!, atFrame: rect0)
        let image1 = imageFromView(view: (fromVC?.view)!, atFrame: rect1)

        let imageView0 = UIImageView(image: image0)
        let imageView1 = UIImageView(image: image1)

//        contentView.addSubview((fromVC?.view)!)

        contentView.addSubview(toVC.view)
        contentView.addSubview(imageView0)
        contentView.addSubview(imageView1)

        UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: {
            imageView0.layer.transform = CATransform3DMakeTranslation(0, -screenHeight / 2, 0)
            imageView1.layer.transform = CATransform3DMakeTranslation(0, screenHeight / 2, 0)
        }) { (isSuccess) in
            transitionContext.completeTransition(true)
            imageView0.removeFromSuperview()
            imageView1.removeFromSuperview()
        }
    }

    //实现dismiss动画逻辑代码
    func dismissAnimation(transitionContext : UIViewControllerContextTransitioning){
        let fromVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.from)
        let toVC = transitionContext.viewController(forKey: UITransitionContextViewControllerKey.to)
        let contentView = transitionContext.containerView

        let screenWidth = UIScreen.main.bounds.size.width
        let screenHeight = UIScreen.main.bounds.size.height

        var rect0 : CGRect!
        var rect1 : CGRect!

        rect0 = CGRect(x: 0, y: 0, width: screenWidth, height: screenHeight/2)
        rect1 = CGRect(x: 0, y: screenHeight/2, width: screenWidth, height: screenWidth)

        let image0 = imageFromView(view: (toVC?.view)!, atFrame: rect0)
        let image1 = imageFromView(view: (toVC?.view)!, atFrame: rect1)

        let imageView0 = UIImageView(image: image0)
        let imageView1 = UIImageView(image: image1)


//        contentView.addSubview((fromVC?.view)!)
//        contentView.addSubview((toVC?.view)!)
        contentView.addSubview(imageView0)
        contentView.addSubview(imageView1)

        toVC?.view.isHidden = true

        imageView0.layer.transform = CATransform3DMakeTranslation(0, -screenHeight / 2, 0)
        imageView1.layer.transform = CATransform3DMakeTranslation(0, screenHeight / 2, 0)

        UIView.animate(withDuration: self.transitionDuration(using: transitionContext), animations: {
            imageView0.layer.transform = CATransform3DIdentity
            imageView1.layer.transform = CATransform3DIdentity
        }) { (isSuccess) in
            transitionContext.completeTransition(true)
            toVC?.view.isHidden = false
            imageView0.removeFromSuperview()
            imageView1.removeFromSuperview()
        }
    }


    /// 截图
    ///
    /// - Parameters:
    ///   - view: view
    ///   - atFrame: rect
    func imageFromView(view : UIView,atFrame:CGRect) -> UIImage {
        UIGraphicsBeginImageContext(view.frame.size)
        let context = UIGraphicsGetCurrentContext()
        context?.saveGState()
        UIRectClip(atFrame)
        view.layer.render(in: context!)
        let theImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return theImage!
    }
}

用法:
在你模态出来的那个界面先实现代理

UIViewControllerTransitioningDelegate

并在viewDidLoad里面实现

        self.navigationController?.modalPresentationStyle = .custom
        self.navigationController?.transitioningDelegate = self

最后实现两个代理

    func animationController(forPresented presented: UIViewController, presenting: UIViewController, source: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CNPresnetOneTransition(transitionType: CNPresentOneTransitionType.Present)
    }

    func animationController(forDismissed dismissed: UIViewController) -> UIViewControllerAnimatedTransitioning? {
        return CNPresnetOneTransition(transitionType: CNPresentOneTransitionType.Dismiss)
    }

【Swift】模态视图的动画展示

相关标签: 模态视图动画