On iOS, I am adding a CALayer to a UITableViewCell's layer. This is my first time using CALayer, and it is simply supposed to change the background color of the table cell. My goal is (1) to learn how to use CALayer, and (2) to test using Instruments whether the drawing is faster than my current implementation, which slows down on CGContextFillRect.
(Technical Q&A QA1708 was the catalyst for all this.)
- (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
// [...]
}
I see the correct colors, but none of the other drawing (I'm assuming the custom drawing ends up behind my new layer).
If I remove the backgroundLayer.frame = ...
line, all of my other drawing is still there, but on a black background.
What am I missing?
The reason why you're getting unexpected behavior is because of UITableViewCell
's relatively complex view hierarchy:
- UITableViewCell
- contentView
- backgroundView
- selectedBackgroundView
Whenever you define custom drawing routines in a UITableViewCell
, you should be doing so within the contentView
hierarchy. This involves subclassing UIView
, overriding -drawRect:
, and adding it as a subview into the contentView
.
The reason why your background color was being ignored in your example was due to your adding your CALayer
as a sublayer of the UITableViewCell
's layer. This is obscured by the UITableViewCell
's contentView
.
However, for some reason, you wish to use a CALayer
here. I'd like to understand why as it doesn't have anything that a UIView
doesn't have. You can set the backgroundColor
on your contentView
instead of doing this roundabout set of things.
Here's an example using CALayer
as you requested:
@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] cgColor]]; //use whatever color you wish.
[self.contentView.layer addSublayer:layer];
}
@end