我有一个UITableView,我试图获得最佳的滚动性能。
单元格不包含任何子视图,所有都在drawRect方法中完成。
每个单元格顶部有一条白线,底部有灰线,顶部和底部之间有线性渐变。除此背景外还有一些文字和图片。
从使用乐器我可以看出,滚动时运行时的主要部分(> 50%)来自线性渐变的绘制。实际上几乎所有这些都来自对CGContextDrawLinearGradient的调用。
有没有一种优化方法?我在想,要么以某种方式缓存线性渐变,要么以另一种方式绘制它...也许绘制一个像素宽然后拉伸它?
以下是我的一些代码:
- (void)drawRect:(CGRect)rect
{
[self drawCellBackground:rect];
[self drawSeparator:rect];
....
}
- (void)drawCellBackground:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGColorRef notQuiteWhiteColor = [UIColor colorWithRed:245.0/255.0 green:245.0/255.0
blue:245.0/255.0 alpha:1.0].CGColor;
CGColorRef lightGrayColor = [UIColor colorWithRed:235.0/255.0 green:235.0/255.0
blue:235.0/255.0 alpha:1.0].CGColor;
drawLinearGradient(context, rect, notQuiteWhiteColor, lightGrayColor);
}
从单独的.c文件:
void drawLinearGradient(CGContextRef context, CGRect rect, CGColorRef startColor, CGColorRef endColor)
{
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGFloat locations[] = { 0.0, 1.0 };
NSArray *colors = [NSArray arrayWithObjects:(id)startColor, (id)endColor, nil];
CGGradientRef gradient = CGGradientCreateWithColors(colorSpace,
(CFArrayRef) colors, locations);
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextSaveGState(context);
CGContextAddRect(context, rect);
CGContextClip(context);
CGContextDrawLinearGradient(context, gradient, startPoint, endPoint, 0);
CGContextRestoreGState(context);
CGGradientRelease(gradient);
CGColorSpaceRelease(colorSpace);
}
答案 0 :(得分:4)
如果你绝对想坚持使用drawRect :(我认为它比旧设备上的单独视图提供更好的性能),为什么不将你的渐变渲染成CGImage或UIImage,然后使用它来绘制-drawRect:?< / p>
此外,您可以提前创建渐变:
static CGGradientRef GetCellBackgroundGradient()
{
static CGGradientRef gradient = NULL ;
if ( !gradient )
{
gradient = // create your CGGradientRef here
}
return gradient;
}
对于高性能代码,您希望尽可能多地预分配内存(内存/对象)。
答案 1 :(得分:2)
您是否正确重用表格视图?如果是这样,在这种情况下,我认为您最好在表格视图上使用子视图,而不是在drawRect:
中进行所有绘图。通过使用子视图,并假设所有单元格的梯度相同,每个可重用单元格只需绘制一次渐变。当它与新内容一起被回收时,只需要更新文本和图像视图,而不必再次绘制渐变。