3

我使用以下代码对 UILabel 进行了子类化,效果很好 - 但任何涉及子类的动画运行速度都比普通 UILabel 慢得多。我假设 Quartz 是罪魁祸首,但我能做些什么来加快速度吗?

- (void)drawTextInRect:(CGRect)rect
{
    CGSize shadowOffset = self.shadowOffset;
    UIColor *textColor = self.textColor;

    // Establish the Quartz 2D drawing destination:
    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSetLineWidth(context, 1);
    CGContextSetLineJoin(context, kCGLineJoinRound);

    // Draw the label’s outline:
    CGContextSetTextDrawingMode(context, kCGTextStroke);
    self.textColor = [UIColor whiteColor];
    [super drawTextInRect:rect];

    // Draw the label:
    CGContextSetTextDrawingMode(context, kCGTextFill);
    self.textColor = [UIColor textColor];
    self.shadowOffset = CGSizeMake(0, 0);
    [super drawTextInRect:rect];

    self.shadowOffset = shadowOffset;
}
4

2 回答 2

5

@MobileOverlord 所说的当然是适用的,尤其是关于分析的部分。

我会注意到设置 shouldRasterize=YES 不是一个包罗万象的解决方案(如果是这种情况,Apple 为什么不将其设置为默认值?)。是的,它可以提高滚动性能,但这样做会以消耗内存为代价,因为您最终可能会在缓存中放置一堆大图像。

它还会在创建时产生开销,我相信(但必须检查以确保)包括一个离屏渲染通道来实际创建光栅化副本。根据层的使用方式,这实际上可能会损害性能。

另一个需要考虑的因素是您的视图是否具有透明度。如果您可以向框架保证您的视图是不透明的(参见 setOpaque/isOpaque),它们可以通过不考虑与 Alpha 通道相关的所有复杂性等来优化渲染。类似的考虑适用于 CALayer。

最后,在您展示的代码块之外,您是否对支持层做了任何偷偷摸摸的事情(例如设置阴影或圆角半径)?这也是杀死动画性能的一种快速方法。

于 2012-02-07T01:13:20.553 回答
3

绘制完标签后,您可以调用shouldRasterize它的图层,它应该会加快动画速度。

shouldRasterize 一个布尔值,指示图层在合成之前是否渲染为位图。动画

@property BOOL shouldRasterize 讨论当此属性的值为 YES 时,图层在其本地坐标空间中呈现为位图,然后与任何其他内容合成到目的地。阴影效果和滤镜属性中的任何滤镜都被光栅化并包含在位图中。但是,图层的当前不透明度未栅格化。如果光栅化位图在合成过程中需要缩放,则根据需要应用 minificationFilter 和 magnificationFilter 属性中的过滤器。

当此属性的值为 NO 时,图层将尽可能直接合成到目标中。如果合成模型的某些特征(例如包含过滤器)需要,图层仍可以在合成之前进行光栅化。

此属性的默认值为 NO。

来自CALayer 类参考

模拟器总是会给你比设备更好的结果,因为它能够使用你系统的全部处理能力和内存。你通常会以这种方式得到有缺陷的结果。每当您结合 CoreAnimation 进行 CoreGraphics 绘图时,在真实设备上测试结果非常重要。

为此,您可以尝试在 Instruments Core Animation Tool 中运行您的应用程序以尝试找出罪魁祸首。看看我的教程。

Instruments – 优化核心动画

于 2012-02-07T00:43:03.153 回答