美文网首页tom动画time
扩大动画效果,希望你喜欢

扩大动画效果,希望你喜欢

作者: iOS_成才录 | 来源:发表于2016-05-21 01:14 被阅读511次

    1. view 分类: 动画类抽取

    • 效果图
    效果图.gif
    import UIKit
    
    var kDefaultLayerBgColor = UIColor.cyanColor().CGColor
    
    // 扩大方法  CGRectInset(rect, dx, dy) -> 以原rect为中心,再参考dx,dy,进行缩放或者放大, -radius 放大
    func expend(center: CGPoint, radius: CGFloat) -> CGRect{
        return CGRectInset(CGRect(origin: center, size: CGSizeZero), -radius,  -radius)
    }
    
    extension UIView{
        
        /**
         view 执行圆形动画效果
         
         - parameter durantion:        动画时长
         - parameter blewLayer:        扩大的 layer,在 哪个 layer下面:如果 传nil ,就添加到当前视图 的最前面(遮挡下面的layer)
         - parameter circleCenter:     圆心
         - parameter isOpen:           是打开,还是关闭效果
         - parameter animationHandle:  进行动画事的处理事件  : layer -》 扩大 遮盖层layer,我们可以对其进行 处理,如:进行透明度 等动画效果,等等
         - parameter completionHandle: 整个动画完成处理事件
         */
        func animateCircleAnimation(duration durantion: NSTimeInterval,  blewLayer: CALayer? = nil, circleCenter: CGPoint, isOpen: Bool, @noescape animationHandle: (layer: CALayer)-> Void, completionHandle: ((Bool) -> Void)? = nil){
            
            let fillLayer = CALayer()
            fillLayer.frame = self.bounds
       
            if let _ = blewLayer{
                layer.insertSublayer(fillLayer, below: blewLayer)
                
            }else{
                layer.addSublayer(fillLayer)
            }
            
            // 获取在 holdView 的中心点
            let center = circleCenter
            
            // 利用勾股定理,求出 圆半径
            let x = max(center.x, frame.width - center.x)
            let y = max(center.y, frame.height - center.y)
            
            let circleRadius = sqrt(x*x + y*y)
            
            // 创建动画对象
            var animation: CircleShowAnimator
            
            if isOpen{
                fillLayer.opacity = 0.99
                animation = CircleShowAnimator(layer: fillLayer, center: center, startRadius: 0, endRadius: circleRadius)
            }else{
                fillLayer.opacity = 0.99
                animation = CircleShowAnimator(layer: fillLayer, center: center, startRadius: circleRadius, endRadius: 0)
            }
            
            animation.duration = durantion
            animation.completion = { layer in
                    fillLayer.removeFromSuperlayer()
        
                    if let _ = completionHandle{
                        completionHandle!(true)
                    }
                
            }
            
            animation.show()
            animationHandle(layer: animation.layer)
        }
    }
    
    class CircleShowAnimator {
        
        var completion: () -> Void = {}
        
        var layer: CALayer
        private let mask: CAShapeLayer
        private let animation: CABasicAnimation
        
        var duration: CFTimeInterval {
            get { return animation.duration }
            set(value) { animation.duration = value }
        }
        
        var timingFunction: CAMediaTimingFunction! {
            get { return animation.timingFunction }
            set(value) { animation.timingFunction = value }
        }
        
        
        init(layer: CALayer, center: CGPoint, startRadius: CGFloat, endRadius: CGFloat, isOpen: Bool = false){
            
            
            // 大小圆路径
            let startCirclePath = CGPathCreateWithEllipseInRect(expend(center, radius: startRadius), nil)
            let endCirclePath = CGPathCreateWithEllipseInRect(expend(center, radius: endRadius), nil)
            
            var startPath = startCirclePath, endPath = endCirclePath
            
            if isOpen{
                var path = CGPathCreateMutable()
                CGPathAddRect(path, nil, layer.bounds)
                CGPathAddPath(path, nil, startCirclePath)
                
                startPath = path
                
                path = CGPathCreateMutable()
                CGPathAddRect(path, nil, layer.bounds)
                CGPathAddPath(path, nil, endCirclePath)
                
                endPath = path
            }
            
            self.layer = layer
            self.layer.backgroundColor = kDefaultLayerBgColor
            
            // CAShapeLayer
            mask = CAShapeLayer()
            mask.path = endPath
            mask.fillRule = kCAFillRuleEvenOdd
            
            animation = CABasicAnimation(keyPath: "path")
            animation.fromValue = startPath
            animation.toValue = endPath
            
            animation.duration = duration
            
            animation.delegate = AnimationDelegate(completion: { () -> Void in
                layer.mask = nil
                self.completion()
                self.animation.delegate = nil
            })
        }
        
        func show(){
            layer.mask = mask
            mask.frame = layer.bounds
            mask.addAnimation(animation, forKey: "circleAnima")
        }
    }
    
    class AnimationDelegate{
        
        private let completion: () -> Void
        
        init(completion: () -> Void) {
            self.completion = completion
        }
        
        dynamic func animationDidStop(_: CAAnimation, finished: Bool) {
            completion()
        }
    }
    

    2. 使用

    
    import UIKit
    
    class CircleAnimationViewController: UIViewController {
    
        lazy var startBtn: UIButton = {
           
            let btn = UIButton()
            btn.size = CGSizeMake(200, 54)
            btn.alpha = 0.8
            
            btn.layer.borderColor = UIColor.orangeColor().CGColor
            btn.layer.borderWidth = 1
            btn.layer.cornerRadius = 27
            btn.layer.masksToBounds = true
            
            btn.setTitle("点击", forState: .Normal)
            btn.setTitle("跳转", forState: UIControlState.Highlighted)
            
            btn.backgroundColor = UIColor.blackColor()
            
            btn.addTarget(self, action: "startBtnClick", forControlEvents: UIControlEvents.TouchDown)
            
            btn.center = self.view.center
    
            return btn
        }()
        
        lazy var LoadBtn: UIButton = {
            
            let btn = UIButton()
            btn.frame = CGRectMake(20, 80, 60, 60)
            btn.alpha = 0.8
            
            btn.layer.borderColor = UIColor.orangeColor().CGColor
            btn.layer.borderWidth = 1
            btn.layer.cornerRadius = btn.frame.size.width / 2
            btn.layer.masksToBounds = true
            
            btn.setTitle("点击", forState: .Normal)
        
            btn.backgroundColor = UIColor.blueColor()
            
            btn.addTarget(self, action: "enterBtnClick:", forControlEvents: UIControlEvents.TouchUpInside)
         
            return btn
        }()
    
        override func viewDidLoad() {
            super.viewDidLoad()
    
            self.view.backgroundColor = UIColor.whiteColor()
            
            self.view.addSubview(self.startBtn)
            self.view.addSubview(LoadBtn)
        }
    
        
        func startBtnClick(){
            
            let center = CGPoint(x: self.startBtn.bounds.midX, y: self.startBtn.bounds.midY)
            
            // 点击按钮进行 扩大动画,动画结束 切换 视图
            self.startBtn.animateCircleAnimation(duration: 0.5, blewLayer: self.startBtn.imageView?.layer, circleCenter: center, isOpen: true, animationHandle: { (layer) -> Void in
                
                // 修改 layer 的背景颜色
                layer.backgroundColor = UIColor.greenColor().CGColor
                
                layer.opacity = 0
                
                let opacityAnim = CABasicAnimation(keyPath: "opacity")
                opacityAnim.fromValue = 0.9
                opacityAnim.toValue = 0.6
                opacityAnim.duration = 0.5
              
                layer.addAnimation(opacityAnim, forKey: "opacity")
                
            }) { (_) -> Void in
                self.navigationController?.pushViewController(Nav3ViewController(), animated: true)
            }
        }
        
        func enterBtnClick(sender: UIButton){
            
            // 效果一: 扩大动画 在 按钮 下面  blewLayer: sender.layer, 按钮 未被遮盖效果
            self.view.animateCircleAnimation(duration: 0.5, blewLayer: sender.layer, circleCenter: sender.center, isOpen: true, animationHandle: { (layer) -> Void in
                
            }) { (_) -> Void in
                
                self.navigationController?.pushViewController(Nav3ViewController(), animated: false)
            }
            
            
            // 效果而: 扩大 动画在按钮上面 ,  blewLayer 参数未传值, 按钮被遮盖 的效果
            /*
             
             self.view.animateCircleAnimation(duration: 0.5, circleCenter: sender.center, isOpen: true, animationHandle: { (layer) -> Void in
             
             }) { (_) -> Void in
             
             self.navigationController?.pushViewController(Nav3ViewController(), animated: false)
             }
             
            */
        }
    }
    
    • Nav3ViewController 部分代码
    // 返回按钮
    lazy var backBtn: UIButton = {
            
            let btn = UIButton(frame: CGRectMake(15, 24, 27, 27))
            btn.addTarget(self, action: "backBtnClick:", forControlEvents: UIControlEvents.TouchUpInside)
            
            btn.setImage(UIImage(named: "back_normal"), forState: UIControlState.Normal)
            
            return btn
            }()
    
    // 2. 返回按钮事件:处理, 退出当前控制器,缩小动画
    
       func backBtnClick(sender: UIButton){
            
            self.view.animateCircleAnimation(duration: 0.5, blewLayer: sender.layer, circleCenter: sender.center, isOpen: false, animationHandle: { (layer) -> Void in
                
    //             self.tableView.hidden = true
    //             self.topScaleImageView.hidden = true
                
                }) { (_) -> Void in
                    self.navigationController?.popViewControllerAnimated(false)
            }
    
    • 当然 如果你觉得 圆形扩大路径不是你想要的效果,你可以 尝试 改变 CGPath,就动态设定 属于你的 扩大缩小动画

    相关文章

      网友评论

      • 文兴:这个用转场动画实现比较自然

      本文标题:扩大动画效果,希望你喜欢

      本文链接:https://www.haomeiwen.com/subject/mhjnrttx.html