iOS - QuartzCore

 

QuartzCore


     

      说起QuartzCore不知道有多少小伙伴很容易和Quartz2D、CoreGraphics等混淆在一起傻傻分不清楚?所以在下面我们先把这几个很容易混淆或者是分不清楚的框架稍加整理。

      1. Quartz2D是CoreGraphics的一部分API的抽象,不是实际存在的.framework 

      2. CoreGraphics定义了颜色、位置、字体、路径、图片等UIKit的常见属性。是构成UIKit的基石。

      3. QuartzCore里面的类以CA开头,就像CG开头的一般都是CoreGraphics框架里面的一样,我们留一个基本的印象,以后遇到可以区分它属于那个框架。

      QuartzCore这个框架也许在一些同行的印象中以为就是 Layer +  Path 也就是用来 “画画”的,其实这个框架里面的东西当仔细研究的时候还是很庞大的,就像我们以前有说过的 AVFoundation 一样的,这篇文章的主要目就是下面这一段内容,简单的介绍一下QuartzCore里面的东西,然后你知道它里面的东西都是用来干什么的,当你要具体的了解里面的东西的时候你需要看什么文章。

      下面的内容就是先告诉你这个类是用来干什么的,然后当你要具体了解里面的东西的时候有一些学习连接给你去了解:

    

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
import Foundation
 
import QuartzCore.CoreAnimation      
 
import QuartzCore
 
import QuartzCore.CAAnimation               ///  庞大的动画架构
 
import QuartzCore.CABase
 
import QuartzCore.CADisplayLink             ///  一个类似于定时器的link
 
import QuartzCore.CAEAGLLayer               ///   用来显示任意的OpenGL图形
 
import QuartzCore.CAEmitterCell             ///   粒子动画 https://www.jianshu.com/p/9fa8bc02117c
 
import QuartzCore.CAEmitterLayer            ///   粒子动画 Emitter发射器
 
import QuartzCore.CAGradientLayer           ///   渐变使用
 
import QuartzCore.CALayer
 
import QuartzCore.CAMediaTiming             ///    所有的动画框架都遵守这个协议
 
import QuartzCore.CAMediaTimingFunction
 
import QuartzCore.CAMetalLayer              ///   https://www.jianshu.com/p/ee163fc050e4     https://developer.apple.com/documentation/quartzcore/cametallayer
 
import QuartzCore.CAReplicatorLayer         ///  重复执行某个操作的layer
 
import QuartzCore.CAScrollLayer             ///  CAScrollLayer提供了和UIScrollView的基本功能。只不过它是layer,只负责显示,不响应用户事件,也不提供滚动条。
 
import QuartzCore.CAShapeLayer              ///  形状Layer
 
import QuartzCore.CATextLayer               ///  它以图层的形式包含了UILabel几乎所有的绘制特性,并且额外提供了一些新的特性。 https://www.jianshu.com/p/df115ffc1076
 
import QuartzCore.CATiledLayer              ///  CATiledLayer为载入大图造成的性能问题提供了一个解决方案  https://www.jianshu.com/p/ee0628629f92
 
import QuartzCore.CATransaction             ///  CATransaction是 Core Animation 中的事务类  https://www.jianshu.com/p/5e02a8a56cc5
 
import QuartzCore.CATransform3D             ///  https://www.jianshu.com/p/3dd14cfbdc53
 
import QuartzCore.CATransformLayer
 
import QuartzCore.CAValueFunction

 

      上面的连接和文字说明就大致说了QuartzCore里面的类都是用来干什么的,然后在下面着了一个我不怎么熟悉的CAEmitterLayer来写一个简单的粒子动画吧。

     

 CAEmitterLayer 粒子动画


 

      拿其中的这个我们写一个简单的粒子动画,在QuartzCore里面别的Layer应该是使用的比较多的,比如像 CAGradientLayer、CAReplicatorLayer、CAShapeLayer这几个我们平常还是在使用的,但这个CAEmitterLayer我还真的见得比较少,然后就看了一下它的一些具体的使用,总结写了一个动画,动画的效果如下图所示:

 

      下面是上面这个效果的代码,里面拥戴的都加了注释:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
import Foundation
import UIKit
 
class PPEmitterButton: UIControl {
     
    let emitterName = "emitterButton"
     
    ///  给外部读取按钮的状态
    var buttonSelected: Bool{
        set(newValue) {
            self.chose = newValue
        }
        get{
            return self.chose
        }
    }
     
    var normalImage  :UIImage?
    var selectedImage:UIImage?
    var effectlImage :UIImage?
    /// 记录按钮状态
    private var chose :Bool = false
     
    lazy var imageView: UIImageView = {
         
        let imageView = UIImageView()
        imageView.isUserInteractionEnabled = true
        imageView.image = self.normalImage
         
        let tap UITapGestureRecognizer.init(target: self, action: #selector(imageViewTap))
        imageView.addGestureRecognizer(tap)
        return imageView
    }()
     
     
    lazy var emitterLayer: CAEmitterLayer = {
         
        let emitterLayer = CAEmitterLayer()
        /// 设置发射源的形状
        emitterLayer.emitterShape = .circle
        /// 设置发射的模式
        emitterLayer.emitterMode  = .outline
        /// 设置粒子cells
        emitterLayer.emitterCells = [self.emitterCell]
         
        return emitterLayer
    }()
     
     
    lazy var emitterCell: CAEmitterCell = {
         
        let emitterCell  = CAEmitterCell()
        /// 设置粒子
        emitterCell.name = emitterName
        /// 设置粒子速度
        emitterCell.velocity = 40
        /// 设置粒子范围
        emitterCell.velocityRange = 70
        /// 设置粒子参数的速度乘数因子
        emitterCell.birthRate  = 0
        /// 设置粒子生命周期
        emitterCell.lifetime   = 1.0
        /// 设置粒子透明度在生命周期内的改变速度
        emitterCell.alphaSpeed = -1
        /// 设置粒子要展现的图片,是个 CGImageRef 的对象
        emitterCell.contents = self.effectlImage?.cgImage
         
        return emitterCell
    }()
     
    convenience init(frame: CGRect, andNormalImage normalImage:String,
                                    andSelectedImage selectedImage:String,
                                    andEffectImage effectlImage:String) {
         
        self.init(frame:frame)
        self.normalImage   = UIImage(named: normalImage)
        self.selectedImage = UIImage(named: selectedImage)
        self.effectlImage  = UIImage(named: effectlImage)
 
        addSubViews()
    }
     
    func addSubViews() {
         
        imageView.frame = self.bounds
        self.addSubview(self.imageView)
         
        emitterLayer.emitterPosition = CGPoint(x: self.frame.width/2.0, y: self.frame.height/2.0)
        emitterLayer.emitterSize = CGSize(width: self.frame.width, height: self.frame.height)
        self.layer.addSublayer(self.emitterLayer)
    }
     
    /// 点击事件
    @objc func imageViewTap() {
         
        self.chose = !self.chose
        self.setCurrentImage()
        imageView.bounds = CGRect.zero
        UIView.animate(withDuration: 0.25, delay: 0, options: .curveLinear , animations: {
             
            self.imageView.bounds = self.bounds
            if(self.chose) {
                 
                /// 这里我们设置的是粒子的扩散动画,注意下面这个keyPath
                /// emitterCells  是cells
                /// emitterButton 是粒子的名称
                /// birthRate
                let baseAnimation = CABasicAnimation.init(keyPath: "emitterCells.emitterButton.birthRate")
                baseAnimation.fromValue = NSNumber.init(value: 200)
                baseAnimation.toValue   = NSNumber.init(value: 0)
                baseAnimation.duration  = 0;
                baseAnimation.timingFunction  = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeOut)
                /// 添加动画 Key就是粒子名称 (这个自己设定)
                self.emitterLayer.add(baseAnimation, forKey: "HHHHHHH")
            }
        }, completion: nil)
         
    }
     
    /// 设置图片
    func setCurrentImage() {
         
        if self.chose {
            imageView.image = selectedImage
        }else{
            imageView.image = normalImage
        }
    }
}

 

总结


 

      通过上面的东西你可以简单的认识一下 QuartzCore,总的来说就是区分清楚  QuartzCore、CoreGraphics 甚至和CoreImage框架的区分等,这样一扯就扯远了 再比如说到CoreImage那你就还得和GPUImage一起了解一下,看一下他们之间的区别联系和结合使用等等,这些知识可能都不是我们经常会使用到的东西,但这些真的才是重要的知识点呀,多多学习多多提高我们的能力。

      CoreImage和GPUImage的结合使用

      傻傻分不清:Quartz2D、QuartzCore、CoreAnimation、CoreImage、CoreGraphics

      Quartz2D简介

posted @   MrRisingSun  阅读(1162)  评论(0编辑  收藏  举报
编辑推荐:
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话
点击右上角即可分享
微信分享提示