矢量图形
1,-》在touch事件中, 记录UIBezierPath,
-》setNeedsDisplay刷新view, drawRect方法中用path绘画
2,-》用CAShapeLayer,touch事件中国年, 获取UIBezierPath,设置layer的path。CAShapeLayer会依照path绘制图形
脏矩形
1,-》在touch事件中,记录下来每一个Point,
-》setNeedsDisplay刷新view,drawRect方法中用UIImage什么的drawInRect:方法,在对应的这些点上绘制图形。
2,-》在touch事件中,记录下来每一个Point,
-》setNeedsDisplayInRect 刷新区域。
异步绘制
CATiledLayer,drawsAsynchronously
隐式绘制
光栅化(缓存)
离屏渲染
圆角、图层蒙版、阴影(没有缓存)
CAShapeLayer path 用UIBezierPath创建路径
CAShapleLayer contentsCenter 创建可伸缩图片
shadowPath 创建阴影路径
混合和过度绘制
gpu会放弃绘制那些完全被其他图层遮挡的像素,计算一个图层是否被遮挡,相当复杂并且会消耗处理器资源。
同样, 合并不同图层的重叠像素, 即混合, 消耗的资源也是相当大的。
因此不要使用透明图层,尽量减少混合行为。
1, 给视图的backgroundColor设置一个固定的,不透明的颜色。
2, 设置opaque属性为YES
减少图层数量
在做图层优化之前, 你需要确定不是在创建一些不可见的图层, 何为是不可见的图层:
1, 图层在屏幕边界之外, 或是在父图层边界之外。
2, 完全在一个不透明图层之后, alpha是1的图层后面,被完全覆盖了的。
3, 完全透明的图层,即将一个图层alpha设置0,它就是不可见的。
CoreAnimation非常擅长处理对视觉效果无意义的图层,就是它会直接忽略绘制这些不可见的像素。
减少图层数量的方法:
1,处理成千上万个图层时
-》不要一次性实例化所有layer的实例, 计算可视区域,在区域之外的图层就不创建了, 也就是说用懒加载的方式加载完所有要用的视图。
-》 处理相似View或Layer时, 使用对象池存储已经创建的实例,仅当在池中获取View或Layer为空时,在给池子创建新的。
2,CoreGraphics 绘制
如果需要一个富文本的画面, 有UIImageView,UILabel等等, 各种图层和嵌套,生成一个庞大的图层树。
我们可以做一个单一的View, 然后重写drawRect方法,在drawRect中绘制。这样就避免了图层树的分配和操作问题。
3,renderInContext方法--将图层树转为一张图片
用CALayer的renderInContext方法, 可以将图层和自图层,创建一个快照,输出到CoreGraphics上下文,
然后得到一个图片, 他可以直接显示在UIImageView中, 或者作为layer的contents。
总结
软件绘图 是CoreGraphics框架来完成。
CoreGraphics比Core Animation和 OpenGL 效率慢。
效率低, 消耗内存大。
CoreAnimation框架的CALayer的contents,只需要一些鱼自己相关的内存
寄宿图绘消耗一定的内存空间, 直接给contents赋值,并不需要增加额外的照片存储大小。
如果相同的照片,赋给多给layer的contents,内存是公用的。而并不是复制多个图片的内存。
CALayerDelegate协议 drawLayer:inContext:
UIView中的drawRect:方法 ,它是前者的封装
图层就会创建一个绘制上下文, 这个上下文需要的大小的内存可以从这个公式算出来:
图层宽* 图层高 * 4 字节
宽的单位为像素 对于一个 204815264 12M大小了
图层每次重绘的时候,都需要抹除内存, 重新分配内存,重新绘制。
所以软件绘图 代价很昂贵。 除非绝对必要, 应该要避免重回视图。
参考:
https://zsisme.gitbooks.io/ios-/content/chapter15/inexplicit-drawing-text.html