|
8 | 8 |
|
9 | 9 | [](https://paypal.me/DingSongwen) |
10 | 10 |
|
11 | | -# Graph |
12 | | -Core graphs and UIBezierPath |
13 | 11 |
|
14 | | -# QuartZ 2D |
15 | | - |
16 | | -## 绘图要点 |
17 | | -1. 绘图需要在context上 |
18 | | -2. 区分(`UIKit` 和`Core Graphics`方式) |
19 | | - |
20 | | -## 绘图方式 |
21 | | -| 绘图方式 | 特点 | 说明 | |
22 | | -| :-------------- | :-------------- | :--------------------------------------- | |
23 | | -| `Core Graphics` | 在特定的context上绘制 | `Core Graphics`更接近底层,更灵活 | |
24 | | -| `UIKit` | 只能基于当前context绘制 | 接口简单,仅包含`UIImage`,`NSString`,`UIBezierPath`(是对`Core Graphics`框架关于path的封装), `UIColor` | |
25 | | - |
26 | | -### UIKit方式 |
27 | | -* 步骤 |
28 | | - 1. 创建图形相应的UIBezierPath对象 |
29 | | - 2. 设置一些修饰属性 |
30 | | - 3. 渲染 |
31 | | -```swift |
32 | | -let path = UIBezierPath(ovalInRect: CGRectMake(0, 0, 100, 100)) |
33 | | -UIColor.blueColor().setFill() |
34 | | -path.fill() |
35 | | -``` |
36 | | -* 以上代码可以直接时用在一下地方 |
37 | | -1. `UIGraphicsBeginImageContextWithOptions`会自动设置context为当前context |
38 | | -```Swift |
39 | | -UIGraphicsBeginImageContextWithOptions(CGSizeMake(100, 100), false, 0) |
40 | | -// code here... |
41 | | -let image = UIGraphicsGetImageFromCurrentImageContext() |
42 | | -UIGraphicsEndImageContext() |
43 | | -``` |
44 | | -2. UIView 中drawrect, cocoa已配置好context为当前context |
45 | | -```Swift |
46 | | -public override func drawRect(rect: CGRect) { |
47 | | - // code here |
48 | | -} |
49 | | -``` |
50 | | -3. 其它情况,使用以下方式将context:参数转化为当前上下文,方便使用UIBezierPath方式绘制, 然后恢复上下文环境 |
51 | | -```Swift |
52 | | -UIGraphicsPushContext(context) |
53 | | -// code here |
54 | | -UIGraphicsPopContext() |
55 | | -``` |
56 | | - |
57 | | -### Core Graphics方式 |
58 | | -* 步骤类似于`UIBezierPath` |
59 | | -```Swift |
60 | | -CGContextAddEllipseInRect(context, CGRectMake(0, 0, 100, 100)) |
61 | | -CGContextSetFillColorWithColor(context, UIColor.redColor().CGColor) |
62 | | -CGContextFillPath(context) |
63 | | -``` |
64 | | -* 如果持有context上下文,可以直接绘制 |
65 | | -```Swift |
66 | | -func renderWithContext(context:CGContextRef) -> Void { |
67 | | - // code here |
68 | | -} |
69 | | -``` |
70 | | -* 如果没有,可以获取当前context |
71 | | -```swift |
72 | | -let optionalContext = UIGraphicsGetCurrentContext() |
73 | | -guard let context = optionalContext else { return } |
74 | | -// code here |
75 | | -``` |
76 | | - |
77 | | -### UIView 的 `drawRect` |
78 | | -* 默认情况下`UIView`不实现`drawRect`,会实现`drawLayer:inContext:`,程序不进入`drawRect` |
79 | | -* UIView的子类如`UILabel`可能会实现`drawRect`,继承他们时,若重写`drawRect`需要调用`supper` |
80 | | -* 若子类实现`drawRect`, `drawLayer:inContext`会调用`drawRect` |
81 | | - [来源](https://www.zhihu.com/question/24387821) |
82 | | - |
83 | | -## 异步线程绘制 |
84 | | -创建绘图上下文,准备绘图资源,生成图片,都是占用CPU时间的,最后一步提交GPU渲染也会卡当前线程 |
85 | | - |
86 | | -| 绘制线程 | 适用情况 | 代码 | |
87 | | -| :--- | :---------------------- | :--------------------------------------- | |
88 | | -| 异步线程 | 仅用于呈现画面,没有交互,容许延迟 | 任意context生成image,或调用`drawInRect`进一步绘制到界面上 | |
89 | | -| 主线程 | 涉及到交互,需要实时绘制,则应当遵循UIKit | 将绘图部分写在`drawRect` | |
| 12 | +基于CoreGraphic的View |
90 | 13 |
|
91 | 14 | *另外还有OpenGL-ES(跨平台基于C API)绘图和Metal(基于OpenGL-ES封装的API,iOS8+ support) [DEMO](DEMO Open-GL/) |
0 commit comments