12

简单说说iOS的图形和动画 - Limboy's HQ

 3 years ago
source link: https://limboy.me/2013/06/08/ios-graphic-animation/
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

简单说说iOS的图形和动画

2013-06-08

Core Graphics

Core Graphics是一组用来绘制2D图形的API,使用CPU进行计算。 新建一个项目时,模板已经自动载入了CoreGraphics.framwork。

Core Animation

Core Animation包含于QuartzCore.framwork中,是一组自由度更大的图形绘制和动画API,但实现起来也会比Core Graphics麻烦一点。iOS上的UIKit和动画效果大部分都是通过Core Animation实现的。

Core Image

Core Image是一组用于图像、视频处理的API,如添加滤镜之类的。

OpenGL / OpenGL ES

底层的图形绘制API,自由度最大,但学习成本也很高。如果不是做大型游戏,推荐使用更高层的API。

硬件加速是指用到了GPU的API,以下这些情况不会用到硬件加速

  • 所有在drawRect中完成的图形绘制。
  • shouldRasterize属性为YES的CALayer。
  • 用到了mask或drop shadow的CALayer。
  • Text (包括UILabels, CATextLayers, Core Text, 等等)。
  • 使用CGContexts绘制的图形

Core Animation

虽然是Animation,但实际上它也干Drawing的活,这就需要CALayer的帮助。iOS中,所有的UIView都自带了一个CALayer(可以通过UIView.layer访问),UIView的渲染和动画最终也是通过layer来实现的。从这个意义上说,UIView就是简单的一层壳,把图形绘制需要的信息传递给layer。当然UIView还有一个重要的功能就是处理事件,如点击按钮,滑动等等。

事实上layer也是一层壳(Model Tree),背后还有呈现树(Presenting Tree)和渲染树(Render Tree),渲染树对呈现树的数据进行渲染。

跟view一样,layer也存在着一个树状结构。可以直接创建,或通过view.layer获取。

layer有很多的动画属性,如anchorPoint(view没有这个属性)、frame、transform等等,详细的属性列表见此。配合Core Animation的API可以实现很多UIView Animation无法实现的效果,比如3D动画。

UIView Animation

这个是我们经常会用到的,它对Core Animation做了更高层的封装,方便使用,当然自由度也降低了。

+ (void)animateWithDuration:(NSTimeInterval)duration delay:(NSTimeInterval)delay options:(UIViewAnimationOptions)options animations:(void (^)(void))animations completion:(void (^)(BOOL finished))completion

animation block里可以设置view的动画属性的终止值,如frame, rotation等。options可以设置动画的相关选项,如下:

enum {
    UIViewAnimationOptionLayoutSubviews            = 1 <<  0,
    UIViewAnimationOptionAllowUserInteraction      = 1 <<  1,
    UIViewAnimationOptionBeginFromCurrentState     = 1 <<  2,
    UIViewAnimationOptionRepeat                    = 1 <<  3,
    UIViewAnimationOptionAutoreverse               = 1 <<  4,
    UIViewAnimationOptionOverrideInheritedDuration = 1 <<  5,
    UIViewAnimationOptionOverrideInheritedCurve    = 1 <<  6,
    UIViewAnimationOptionAllowAnimatedContent      = 1 <<  7,
    UIViewAnimationOptionShowHideTransitionViews   = 1 <<  8,
 
    UIViewAnimationOptionCurveEaseInOut            = 0 << 16,
    UIViewAnimationOptionCurveEaseIn               = 1 << 16,
    UIViewAnimationOptionCurveEaseOut              = 2 << 16,
    UIViewAnimationOptionCurveLinear               = 3 << 16,
 
    UIViewAnimationOptionTransitionNone            = 0 << 20,
    UIViewAnimationOptionTransitionFlipFromLeft    = 1 << 20,
    UIViewAnimationOptionTransitionFlipFromRight   = 2 << 20,
    UIViewAnimationOptionTransitionCurlUp          = 3 << 20,
    UIViewAnimationOptionTransitionCurlDown        = 4 << 20,
    UIViewAnimationOptionTransitionCrossDissolve   = 5 << 20,
    UIViewAnimationOptionTransitionFlipFromTop     = 6 << 20,
    UIViewAnimationOptionTransitionFlipFromBottom  = 7 << 20,
};
typedef NSUInteger UIViewAnimationOptions;

所以一般的动画view animation都可以应付。

TableView优化

TableView是iOS中非常重要的组成部分,如果处理不当,就很容易出现不流畅的现象。比如一个TableViewCell中有多个subview。上面说过一个view对应了一个layer,多个view自然也就对应多个layer,好比photoshop的图层。滑动时GPU需要分别对每一个layer进行处理,如果不能在短时间内完成,就容易掉帧。

要保证TableView的流畅,首先TableViewCell的生成时间要短(少于1/60秒),其次移动时帧频尽量保持在60(也就是每秒60帧)。前者取决于CPU,后者取决于GPU。

以twitter为例,可以通过subviews来实现,不过性能会有点影响,但实现起来简单。

twitter TableViewCell

因为cell在形态上不会经常改变,所以也可以通过drawRect直接绘制,只要这个时间足够短就可以。好处是layer不用处理多个子layer的组合和叠加,就像一张jpg图片一样,滑动会更流畅。

twitter TableViewCell

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK