IOS设计: 图形性能分析
2016-04-23 19:47
393 查看
注:本文只是提取了其中的主要部分进行了翻译,文章出现在较早,现在可能有不同的地方,具体操作请依据新版本的Xcode进行使用,原文还有其他的参考,还是建议大家多看原文 PS:本文第一次翻译,英语较渣,如有翻译不合适的地方请大家留言指出。
显示的内幕
IOS图形显示的层次结构
UIKit是负责IOS的图层管理的接口。他有很多类组成,各个类能够响应具体的UIControl的事件,例如UIButton和UILable。UIKit是CA的上层,CA是用于处理平滑转换的框架。
OpenGL ES是开源的用于处理图形的框架,包括游戏动画和UIKit和CA,CG就是我们常说的Quartz,基于CPU的。
硬件加速就是我们常说的GPU渲染图形,例如用到OPenGL和基于它的CA和UIkit。大多数的动画要想显示的很好都应当使用GPU进行加速。
离屏渲染指的在GPU进行屏幕渲染前是用CPU来处理bitmap图形。以下几种情况会自动进行离屏渲染:
CoreGraphic类(以CG开头的类)
drawRect方法(即使是空实现即在你的代码中显示的声明了)
CALayer的shouldRasterize设为YES
CALayer使用setMaskToBounds或设置阴影setShadow*
任何字体的显示,即使是CoreText
透明组 UIGroupOpacity
我们可以使用Instruments来进行查看离屏渲染的部分
1.把设备连入MAC
2.Xcode中打开Instruments
3.选择IOS>Graphics>CA
4.打开详细面板
5.选择要查看的设备
6.勾选Color OffScreen-Render Yellow 按钮
7.打开设备即可看到离屏渲染的部分,用黄色标识
补充:因为MAC的CPU远高于IOS设备的CPU(这是补充部分。。。),如果要是进行性能测试的话最好用真机显示,如果只是想看本例中的形式,IOS模拟器也可以
用UIButton来举例
使用预渲染
对于保存在磁盘上的图像,当我们用一个UIImage时它默认是GPU进行渲染的,这种事低消耗的而且是利用GPU来伸缩或铺像素进行显示。
CALyer
当我们设置圆角矩形的时候会进行离屏渲染,此时不得不禁用动画。总的来说,如果需要动画,那么它是不可行的
DrawRect
它依赖于CG自定义动画,缺点在于事件处理的时候,一个点击会进行两次的setNeedsDisaplay的调用,增加CPU和内存的负担,特别是多个Button的时候
混合的方法(本文支持和建议的)
如果我们需要灵活的用代码来进行绘画,那么可行的方案是制造一个可伸缩的可重用的bitmap图像给所有的实例
首先常见一个子类集成UIButton,同时加入静态变量
下一步就是画图用Bezier曲线,目标是产生可重用的图像给静态变量
参数NO指的是不透明,0.0指的是缩放比例和设备相同(不同的IOS的缩放比例是不同的视网膜屏的要高于非视网膜屏的,具体比例数据请自行度娘),接下来是用Bezier曲线进行绘图,要考虑到Highlighted的情况
现在就有了实现背景图片的方法,下面是进行封装形成一个通用的初始化方法
测试和运行:将butoon改成本文的子类并将内容改成CGContext-Gradient图像
代码:https://github.com/kaishin/custom-UIButton/blob/master/Custom%20UIButtons/CBHybrid.m
原文链接:https://robots.thoughtbot.com/designing-for-ios-graphics-performance
显示的内幕
IOS图形显示的层次结构
UIKit是负责IOS的图层管理的接口。他有很多类组成,各个类能够响应具体的UIControl的事件,例如UIButton和UILable。UIKit是CA的上层,CA是用于处理平滑转换的框架。
OpenGL ES是开源的用于处理图形的框架,包括游戏动画和UIKit和CA,CG就是我们常说的Quartz,基于CPU的。
硬件加速就是我们常说的GPU渲染图形,例如用到OPenGL和基于它的CA和UIkit。大多数的动画要想显示的很好都应当使用GPU进行加速。
离屏渲染指的在GPU进行屏幕渲染前是用CPU来处理bitmap图形。以下几种情况会自动进行离屏渲染:
CoreGraphic类(以CG开头的类)
drawRect方法(即使是空实现即在你的代码中显示的声明了)
CALayer的shouldRasterize设为YES
CALayer使用setMaskToBounds或设置阴影setShadow*
任何字体的显示,即使是CoreText
透明组 UIGroupOpacity
我们可以使用Instruments来进行查看离屏渲染的部分
1.把设备连入MAC
2.Xcode中打开Instruments
3.选择IOS>Graphics>CA
4.打开详细面板
5.选择要查看的设备
6.勾选Color OffScreen-Render Yellow 按钮
7.打开设备即可看到离屏渲染的部分,用黄色标识
补充:因为MAC的CPU远高于IOS设备的CPU(这是补充部分。。。),如果要是进行性能测试的话最好用真机显示,如果只是想看本例中的形式,IOS模拟器也可以
用UIButton来举例
使用预渲染
对于保存在磁盘上的图像,当我们用一个UIImage时它默认是GPU进行渲染的,这种事低消耗的而且是利用GPU来伸缩或铺像素进行显示。
CALyer
当我们设置圆角矩形的时候会进行离屏渲染,此时不得不禁用动画。总的来说,如果需要动画,那么它是不可行的
DrawRect
它依赖于CG自定义动画,缺点在于事件处理的时候,一个点击会进行两次的setNeedsDisaplay的调用,增加CPU和内存的负担,特别是多个Button的时候
混合的方法(本文支持和建议的)
如果我们需要灵活的用代码来进行绘画,那么可行的方案是制造一个可伸缩的可重用的bitmap图像给所有的实例
首先常见一个子类集成UIButton,同时加入静态变量
// In CBHybrid.m #import "CBHybrid.h" @implementation CBHybrid // Resizable background image for normal state static UIImage *gBackgroundImage; // Resizable background image for highlighted state static UIImage *gBackgroundImageHighlighted; // Background image border radius and height static int borderRadius = 5; static int height = 37;
下一步就是画图用Bezier曲线,目标是产生可重用的图像给静态变量
</pre></div><div style="text-align:left"><pre name="code" class="objc">- (UIImage *)drawBackgroundImageHighlighted:(BOOL)highlighted { // Drawing code goes here }设置图像的宽度(最佳操作设置1pt的可伸缩区域+2*radius,button默认进行背景图像拉伸,设置少了可以体验性能)和高度37pt,接下来bitmap Context
UIGraphicsBeginImageContextWithOptions(CGSizeMake(width, height), NO, 0.0); CGContextRef context = UIGraphicsGetCurrentContext(); CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
参数NO指的是不透明,0.0指的是缩放比例和设备相同(不同的IOS的缩放比例是不同的视网膜屏的要高于非视网膜屏的,具体比例数据请自行度娘),接下来是用Bezier曲线进行绘图,要考虑到Highlighted的情况
// Gradient Declarations // NSArray *gradientColors = ... // Draw rounded rectangle bezier path UIBezierPath *roundedRectanglePath = [UIBezierPath bezierPathWithRoundedRect: CGRectMake(0, 0, width, height) cornerRadius: borderRadius]; // Use the bezier as a clipping path [roundedRectanglePath addClip]; // Use one of the two gradients depending on the state of the button CGGradientRef background = highlighted? highlightedGradient : gradient; // Draw gradient within the path CGContextDrawLinearGradient(context, background, CGPointMake(140, 0), CGPointMake(140, height-1), 0); // Draw border // [borderColor setStroke... // Draw Inner Glow // UIBezierPath *innerGlowRect...输出图像和进行清理工作
现在就有了实现背景图片的方法,下面是进行封装形成一个通用的初始化方法
- (void)setupBackgrounds { // Generate background images if necessary if (!gBackgroundImage && !gBackgroundImageHighlighted) { gBackgroundImage = [[self drawBackgroundImageHighlighted:NO] resizableImageWithCapInsets:UIEdgeInsetsMake(borderRadius, borderRadius, borderRadius, borderRadius) resizingMode:UIImageResizingModeStretch]; gBackgroundImageHighlighted = [[self drawBackgroundImageHighlighted:YES] resizableImageWithCapInsets:UIEdgeInsetsMake(borderRadius, borderRadius, borderRadius, borderRadius) resizingMode:UIImageResizingModeStretch]; } // Set background for the button instance [self setBackgroundImage:gBackgroundImage forState:UIControlStateNormal]; [self setBackgroundImage:gBackgroundImageHighlighted forState:UIControlStateHighlighted]; }返回button类型和如果是用代码创建的button需要实现initWithCoder(或initWithFrame)
测试和运行:将butoon改成本文的子类并将内容改成CGContext-Gradient图像
代码:https://github.com/kaishin/custom-UIButton/blob/master/Custom%20UIButtons/CBHybrid.m
原文链接:https://robots.thoughtbot.com/designing-for-ios-graphics-performance
相关文章推荐
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 深入理解PHP7内核之FAST_ZPP
- 峰回路转,Firefox 浏览器即将重返 iOS 平台
- 不可修补的 iOS 漏洞可能导致 iPhone 4s 到 iPhone X 永久越狱
- iOS 12.4 系统遭黑客破解,漏洞危及数百万用户
- 每日安全资讯:NSO,一家专业入侵 iPhone 的神秘公司
- [转][源代码]Comex公布JailbreakMe 3.0源代码
- Flex 性能优化常用手法总结
- oracle 性能优化建议小结
- Lua性能优化技巧(一):前言
- Lua性能优化技巧(五):削减、重用和回收
- Lua性能优化技巧(三):关于表
- Lua性能优化技巧(四):关于字符串
- SQL Server 2016 查询存储性能优化小结
- MySQL性能优化 出题业务SQL优化
- C#图像处理之霓虹效果实现方法
- C#图像亮度调整的方法
- C#实现图像锐化的方法
- C#图像透明度调整的方法