Swift对CALayer的使用

//
//  EYLayerViewController.swift
//  videomask
//
//  Created by sjh on 2023/8/8.
//

import UIKit

class EYLayerViewController: UIViewController {
    
    var aniLayer = CALayer.init()

    override func viewDidLoad() {
        super.viewDidLoad()

        view.backgroundColor = UIColor.white
        self.view.addSubview(backgroundView)
       
        backgroundView.frame = CGRect(x: 0, y: 0, width: 100, height: 100)
        backgroundView.center = self.view.center
        // Do any additional setup after loading the view.
        
        self.view.layer.addSublayer(aniLayer)
        //💡layer设置布局建议使用position 和 center
        aniLayer.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
        //设置中心点
        aniLayer.position = self.view.center
        aniLayer.backgroundColor = UIColor.green.cgColor
        //锚点的位置 小于0.5,向右➡️移动。 小于0.5 向下⬇️移动(与坐标系相反)
//        aniLayer.anchorPoint = CGPoint.init(x: 1.5, y: 0.5)
        
//        aniLayer.contentsScale = 0.3
     
//        setMask()
        //⚠️mask 会影响 shadow
        setShadow()
    
        //设置图层代理
        aniLayer.delegate = self
        //调用此方法,否则代理方法不会被调用
        aniLayer.setNeedsDisplay()
    }
    
    func setShadow(){
        /*🔔
         1.masksToBounds 目的就是剪切外边框
         2.而shadow 正好在外边框上
         3.如果要显示圆角阴影,可以考虑2个layer去做
         */
        
//        aniLayer.cornerRadius = 25
//        aniLayer.masksToBounds = true
        //阴影位置 小于0,出现在左边。 小于0 出现在上班(与坐标系对应)
//        aniLayer.shadowOffset = CGSize(width: -2, height: -2)
        aniLayer.shadowColor = UIColor.red.cgColor
        aniLayer.shadowOpacity = 1
        //后面展现一个一个半径的阴影
        aniLayer.shadowRadius = 25
 
    }
    
    func setMask(){
        
        
        let mask = CALayer.init()
        //遮罩区域
        mask.bounds = CGRect(x: 0, y: 0, width: 100, height: 100)
        //🔔 遮罩 过大可以显示shadow
//        mask.bounds = CGRect(x: 0, y: 0, width: 120, height: 120)
        mask.position = CGPoint(x: 50, y: 50)
        //显示的透明度 0 透明 -> 1不透明
        mask.opacity = 1
        //设置颜色并没有作用。但是可以使aniLayer 遮罩区域显示出来
        mask.backgroundColor = UIColor.red.cgColor
        mask.borderWidth = 3
        mask.borderColor = UIColor.darkGray.cgColor
        //背景同时消失了
//        mask.isHidden = true
        let scale_ani = aniLayer.contentsScale
        let scale_mask = mask.contentsScale
        EYLog(M: "scale_ani = \(scale_ani),scale_mask = \(scale_mask)")
        
        aniLayer.mask = mask

    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        aniLayer.add(basicAnimation, forKey: "position")
//        aniLayer.add(keyframeAnimation_1, forKey: "transform.rotation")
//        aniLayer.add(keyframeAnimation_2, forKey: "position")#imageLiteral(resourceName: "simulator_screenshot_FA85362A-AA46-412F-A446-473496B53DDF.png")
//        aniLayer.add(transitionAnimation, forKey: "test")
//        aniLayer.add(groupAnimation, forKey: "group")
        //                keyframeAnimation_1()
//        keyframeAnimation_2()
//                springAnimation()
//        transitionAnimation()
//        groupAnimation()
    }
    //CABasicAnimation 基本动画
    /*
     keyPath
     1.position
     2.position.y
     3.position.x
    
     4.transform
     5.transform.x
     6.transform.y
     
     7.bounds
     8.bounds.width
     */
    lazy var basicAnimation: CABasicAnimation = {
        
        let ani = CABasicAnimation.init(keyPath: "position")
        ani.repeatCount = 1
        //默认YES, 代表动画执行完成后从图层移除。 图层恢复到之前的状态
//        ani.isRemovedOnCompletion = true
        //图层保持动画后的状态
        ani.isRemovedOnCompletion = false
        //决定当前对象在非active时间段的行为
        ani.fillMode = .forwards
        //动画开始时间 如: 延迟2s
        ani.beginTime = CACurrentMediaTime() + 2
        //动画时长
        ani.duration = 3;
        //线性,匀速
        ani.timingFunction = CAMediaTimingFunction.init(name: .linear)
        //渐进 慢-快
        ani.timingFunction = CAMediaTimingFunction.init(name: .easeIn)
        //渐出 快-慢
        ani.timingFunction = CAMediaTimingFunction.init(name: .easeOut)
        //渐进渐出 慢-快-慢
        ani.timingFunction = CAMediaTimingFunction.init(name: .easeInEaseOut)
        //起始值 这里指position
//        ani.fromValue = NSValue(cgPoint: CGPointMake(100, 100))
        //插入值 toValue-byValue 开始
        ani.byValue = NSValue(cgPoint: CGPoint(x: 200, y: 400))
        //结束值 这里指position
        ani.toValue = NSValue(cgPoint: CGPointMake(150, 350))
        //支持键值编码
        
        ani.setValue("form", forKey: "name")
        ani.setValue(aniLayer, forKey: "layer")
        
        return ani
    }()
    //CAKeyframeAnimation 关键帧1
    lazy var keyframeAnimation_1: CAKeyframeAnimation = {
        
        let ani = CAKeyframeAnimation(keyPath: "transform.rotation")
        //重复次数
        ani.repeatCount = 1
        //动画时长
        ani.duration = 0.5
        //设置动画的关键点
        ani.values = [0.0,-Double.pi/4,0.0,Double.pi/4,0.0]
        //设置动画关键点对应的时间
        ani.keyTimes = [0.0,0.25,0.5,0.75,1]
        
        ani.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
        //指定keyframe如果计算中间值
        ani.calculationMode = .linear
        //对象沿指定path运动过程中, 绕切线旋转模式
        ani.rotationMode = nil;
        
        return ani
    }()
    
    //CAKeyframeAnimation 关键帧2
    lazy var keyframeAnimation_2: CAKeyframeAnimation = {
        let ani = CAKeyframeAnimation(keyPath: "position")
        ani.repeatCount = 2
        ani.duration = 3
        ani.values = [CGPoint(x: 0, y: 0)
                      ,CGPoint(x: 100,y: 100)
                      ,CGPoint(x: 100, y: 200)
                      ,CGPoint(x: 150, y: 150)
                      ,CGPoint(x: 100, y: 100)
                      ,CGPoint(x: 0, y: 0)].map({NSValue(cgPoint: $0)})
        ani.keyTimes = [0.0,0.2,0.4,0.6,0.8,1]
                
        return ani
    }()
    
    //CATransition 提供layer状态切换的动画
    lazy var transitionAnimation: CATransition = {
        
        let ani = CATransition.init()
        //指定动画起点处于transition的百分比 0.0-1.0 默认0.0
        ani.startProgress = 0.5
        //指定动画终点处于transition的百分比 0.0-1.0 默认1.0 endProgress>startProgress
        ani.endProgress = 1
        
        //type 属性 与 filter 属性冲突。 以filter 为主
        //淡入淡出
        ani.type = .fade
        //图层内容在现有内容之上滑入 ⚠️需要和subType一起使用
//        ani.type = .moveIn
        // 图层内容推动着现有内容进入 ⚠️需要和subType一起使用
        ani.type = .push
        //图层内容根据subType指定方向逐渐显示
        ani.type = .reveal
        //指定transition方向  ⚠️属性 与 filter 属性冲突。 以filter 为主
        ani.subtype = nil;
        // 从图层底部开始
        ani.subtype = .fromBottom
        // 从图层左部开始
        ani.subtype = .fromLeft
        // 从图层右部开始
        ani.subtype = .fromRight
        // 从图层头部开始
        ani.subtype = .fromTop
        //mac才可使用
//        ani.filter =
        ani.duration = 2
        
        ani.isRemovedOnCompletion = true
        
        return ani
    }()
    //CASpringAnimation 弹簧动画
    lazy var springAnimation: CASpringAnimation = {
        
        let ani = CASpringAnimation(keyPath: "position")
        //抑制弹簧运动的摩擦力的大小 值变小,弹簧次数增加
        ani.damping = 50
        //摩擦力变小,settlingDuration 可能大于duration ()
//        ani.settlingDuration = 15
        //运动时长
        ani.duration = 5
        // 初始速度
        ani.initialVelocity = 5
        //挂在弹簧末端的重量, 数值越大 次数越多,幅度越大 settlingDuration也会变大
        ani.mass = 10
        //弹簧刚性系数
        ani.stiffness = 1000
        
        ani.repeatCount = 2
        
        ani.isRemovedOnCompletion = true
        
        ani.fillMode = .forwards
        
        ani.fromValue = NSValue(cgPoint: CGPoint(x: 100, y: 100))
        
        ani.toValue = NSValue(cgPoint: CGPoint(x: 100, y: 500))
        
        ani.delegate = self
        
        return ani
        
    }()
    
    lazy var groupAnimation: CAAnimationGroup = {
        
        let ani_group = CAAnimationGroup()
        //添加动画
        ani_group.animations = [springAnimation, keyframeAnimation_1]
        //动画时长 依此为主
        ani_group.duration = 15
        //动画开始时间
        ani_group.beginTime = CACurrentMediaTime() + 1
        
        ani_group.delegate = self
       
        return ani_group
    }()
    
    
    override func viewDidAppear(_ animated: Bool) {
        super.viewDidAppear(animated)

    }
    
    

    fileprivate lazy var backgroundView = {
        let view = UIView.init()
        view.backgroundColor = UIColor.red
        return view
    }()
  

}

extension EYLayerViewController: CAAnimationDelegate{
    
    
    func animationDidStart(_ anim: CAAnimation) {
        
    }
    
    //flag :到达duration时间 = true , 未到达duration时间 = false
    func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
        
    }
}

extension EYLayerViewController: CALayerDelegate{
    
    
    
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值