Я использую несколько CALayers для рисования своего контента в подклассе UITableViewCell. Предполагается, что фактическое рисование вызывается методом делегата CALayer drawLayer: inContext :. Однако методы делегата никогда не вызываются.
Вот моя структура:
- CustomCell: UITalbeViewCell
- создает CustomCellContentView: UIView
- создает CABackgroundLayer: CALayer
- создает CATextLayer: CALayer
- создает CALayerDelegate: NSObject
Каждый customCell имеет customContentView, который содержит все CALayers для рисования.
Каждый customCell создает caLayerDelegate для вызова CALayers. CaLayerDelegate отправляет отчет в customCell.
CustomCell:
#define CALAYER_TEXTLAYER_NAME @"CATextLayer"
#define CALAYER_BGLAYER_NAME @"CABackgroundLayer"
...
- (id) customContentViewForCurrentCell
{
CGRect contentViewFrame = CGRectMake(-CC_LEFTRIGHT_PADDING, 0., self.contentView.bounds.size.width, self.contentView.bounds.size.height);
CustomCellContentView *cellContentView = [[[CustomCellContentView alloc] initWithFrame: contentViewFrame] autorelease];
CALayerDelegate *layerDelegate = [[CALayerDelegate alloc] initWithView: self];
cellContentView.layerDelegate = layerDelegate;
[cellContentView setupSubLayers];
[layerDelegate release];
return cellContentView;
}
#pragma mark - Initialisation
- (id)initWithStyle:(UITableViewCellStyle)style reuseIdentifier:(NSString *)reuseIdentifier
{
self = [super initWithStyle:style reuseIdentifier:reuseIdentifier];
if (!self)
return nil;
self.customContentView = (CustomCellContentView *)[self customContentViewForCurrentCell];
self.customContentView.opaque = TRUE;
self.backgroundColor = [UIColor clearColor];
self.selectionStyle = UITableViewCellSelectionStyleNone;
[self.contentView addSubview: self.customContentView];
return self;
}
#pragma mark - Cell Update
- (void) refreshLayout
{
[self setNeedsDisplay];
[self.customContentView setNeedsDisplay];
}
...
#pragma mark - CALayer Delegate Methods
-(void) drawLayer: (CALayer*) layer inContext: (CGContextRef) context
{
}
-(void) drawCABackgroundLayer: (CALayer*) layer inContext: (CGContextRef) context
{
UIGraphicsPushContext(context);
CGRect contentRect = [layer bounds];
UIImage *bgImage = [[ImageCacheController sharedImageCache] imageFromCache: GENERIC_BGIMAGE_FILENAME];
[bgImage drawInRect: CGRectMake(contentRect.origin.x, contentRect.origin.y, contentRect.size.width, contentRect.size.height)];
UIGraphicsPopContext();
}
-(void) drawCATextLayer: (CALayer*) layer inContext: (CGContextRef) context
{
UIGraphicsPushContext(context);
CGContextSetShadowWithColor(context, CGSizeMake(0.f, 2.0f), 0.0f, [UIColor mainLabelShadowColor].CGColor);
[[UIColor mainLabelColor] set];
UIFont *mainFont = [UIFont fontWithName: FONT_INFOS size: CC_MAINLABEL_FONTSIZE_MAX];
[@"ArthurDent" drawAtPoint: [self mainViewPosition]
forWidth: CC_MAINLABEL_WIDTH
withFont: mainFont
minFontSize: CC_MAINLABEL_FONTSIZE_MAX
actualFontSize: NULL
lineBreakMode: UILineBreakModeTailTruncation
baselineAdjustment: UIBaselineAdjustmentAlignBaselines];
UIGraphicsPopContext();
}
CustomCellContentView:
@interface CustomCellContentView : UIView
{
CALayerDelegate *layerDelegate;
CALayer *backgroundLayer;
CALayer *textLayer;
}
@property (nonatomic, retain) CALayerDelegate *layerDelegate;
@property (nonatomic, retain) CALayer *backgroundLayer;
@property (nonatomic, retain) CALayer *textLayer;
- (void) setupSubLayers;
@end
@implementation CustomCellContentView
@synthesize textLayer, backgroundLayer, layerDelegate;
#pragma mark - Initialisation
- (id) initWithFrame:(CGRect)frame
{
self = [super initWithFrame: frame];
if(!self)
return nil;
return self;
}
- (void) setupSubLayers
{
self.textLayer = [CALayer layer];
self.textLayer.name = CALAYER_TEXTLAYER_NAME;
self.textLayer.shadowColor = [UIColor mainLabelShadowColor].CGColor;
self.textLayer.shadowOffset = CGSizeMake(0.0f, 2.0f);
self.textLayer.shadowOpacity = 1.f;
self.textLayer.shadowRadius = 0.f;
self.textLayer.needsDisplayOnBoundsChange = TRUE;
self.textLayer.delegate = self.layerDelegate;
self.backgroundLayer = [CALayer layer];
self.backgroundLayer.name = CALAYER_BGLAYER_NAME;
self.backgroundLayer.needsDisplayOnBoundsChange = TRUE;
self.backgroundLayer.delegate = self.layerDelegate;
[self.layer addSublayer: self.textLayer];
[self.layer addSublayer: self.backgroundLayer];
[self.textLayer setNeedsDisplay];
[self.backgroundLayer setNeedsDisplay];
}
#pragma mark - SetNeedsDisplay Overwritten
- (void) setNeedsDisplay
{
[super setNeedsDisplay];
[self.layer setNeedsDisplay];
[self.textLayer setNeedsDisplay];
[self.backgroundLayer setNeedsDisplay];
}
...
CALayerDelegate:
@implementation CALayerDelegate
#pragma mark - Initialisation
-(id) initWithView: (UIView *) view
{
self = [super init];
if (!self)
return nil;
_view = view;
return self;
}
#pragma mark - CALayer Delegate Methods
-(void) drawLayer: (CALayer*) layer inContext: (CGContextRef) context
{
NSString* methodName = [NSString stringWithFormat: @"draw%@:inContext:", [layer name]];
SEL selector = NSSelectorFromString(methodName);
if (![_view respondsToSelector: selector])
selector = @selector(drawLayer:inContext:);
[_view performSelector: selector
withObject: layer
withObject: (id)context];
}
@end
Я читал для UIViewController, лучше создавать под-CALayers в awakeFromNib:, а не в initWithFrame:, потому что есть некоторая форма поддержки слоя, происходящая после initWithFrame:, которая отбрасывает создание подслоев. Итак, вы должны добавлять подслои только после загрузки представления?
Я использую отдельные CALayerDelegate - объекты, поэтому CustomCell и его представление отвечают только за customContentView.layer.
Кто-нибудь знает, что я делаю не так?
Заранее спасибо !!