2013-03-04 138 views
1

在iOS上,我将CALayer添加到UITableViewCell的图层。这是我第一次使用CALayer,它只是应该改变表格单元格的背景颜色。我的目标是(1)学习如何使用CALayer,以及(2)使用Instruments来测试绘图是否比我当前的实现更快,这会降低CGContextFillRect的速度。使用CALayer设置UITableViewCell背景颜色

Technical Q&A QA1708是这一切的催化剂。)

实施现状的(作品)

- (void)drawRect:(CGRect)r 
{ 
    UIColor *myColor = [self someColor]; 
    [myColor set]; 
    CGContextRef context = UIGraphicsGetCurrentContext(); 
    CGContextFillRect(context, r); // draw the background color 
    // now draw everything else 
    // [...] 

} 

尝试新的实现(不工作)

#import <QuartzCore/QuartzCore.h> 

@implementation MyCell { 
    CALayer *backgroundLayer; 
} 

- (id) initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 

    if (self) { 
     // [...other stuff here too] 
     backgroundLayer = [[CALayer alloc] init]; 
     [[self layer] addSublayer:backgroundLayer]; 
    } 

    return self; 
} 

- (void)drawRect:(CGRect)r { 
    backgroundLayer.frame = CGRectMake(0, 0, r.size.width, r.size.height); 
    [backgroundLayer setBackgroundColor:[self someColor]]; 
    // now draw everything else 
    // [...] 
} 

我看到正确的颜色,但没有其他绘图(我假设自定义绘图结束后面我的新层)。

如果我删除backgroundLayer.frame = ...行,我所有其他绘图仍然存在,但在黑色背景上。

我错过了什么?

+2

试着用'insertSublayer:atIndex:0',而不是'addSublayer:'。这将该图层置于子图层数组的底部。操作系统使用图层'zPosition'和子图层数组中的相对位置来确定哪个图层可见,哪些图层被遮挡。 – 2013-03-04 22:47:28

+0

@Aaron Brager你为什么在这里使用'CALayer'?你想用它做什么,你不能在'UIView'上做什么? – 2013-03-05 02:39:00

+0

@DanielMartín那没用。在索引0和1处,我只是得到一个黑色背景; 2和更高我没有看到我的绘图。 – 2013-03-05 07:14:36

回答

3

为什么你得到意外行为的原因是因为UITableViewCell的相对复杂的视图层次:

- UITableViewCell 
    - contentView 
    - backgroundView 
    - selectedBackgroundView 

每当在UITableViewCell定义自定义绘图程序,你应该在contentView层次结构中这样做。这包括继承UIView,覆盖-drawRect:,并将其作为子视图添加到contentView中。

为什么你的背景颜色是你的榜样被忽略的原因是由于您的加入您的CALayerUITableViewCell的层的子层。这被UITableViewCellcontentView所掩盖。

但是,由于某种原因,您希望在此处使用CALayer。我想了解为什么它没有UIView没有的东西。你可以在你的contentView上设置backgroundColor,而不是做这个迂回的事情。

下面是一个例子使用CALayer按照您的要求:

@implementation JRTableViewCell 

- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier { 
    self = [super initWithStyle:style reuseIdentifier:reuseIdentifier]; 
    if(self) { 
     [self addCustomLayerToContentView]; 
    } 
    return self; 
} 

- (void)addCustomLayerToContentView { 
    CALayer *layer = [[CALayer alloc] initWithFrame:[self bounds]]; 
    [layer setBackgroundColor:[UIColor blueColor]]; //use whatever color you wish. 

    [self.contentView.layer addSublayer:layer]; 
} 

@end 
+2

谢谢。这个改变使我的'drawRect'函数的执行时间减少了几秒钟,现在我的表格以每秒56-58帧而不是40-45 FPS的速度滚动。 – 2013-03-07 21:41:05

+2

没有'initWithFrame:'方法,'setBackgroundColor:'有'CGColorRef',而不是'UIColor'。 – pr1001 2015-05-12 22:06:24