我正在使用几个CALayers在UITableViewCell子类中绘制我的内容。实际绘图应该通过调用CALayer委托方法drawLayer:inContext:来实现。 但委托方法永远不会被调用。
这是我的结构:
每个customCell都有一个customContentView,它包含所有用于绘图的CALayers。 每个customCell都会为要调用的CALayers创建一个caLayerDelegate。 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,最好在awakeFromNib中创建子CALayers:而不是在initWithFrame:中,因为在initWithFrame:之后会出现某种形式的层 - 支持,这会丢弃子层的创建。那么,您应该只在加载视图后添加子图层?
我使用单独的CALayerDelegate - 对象,因此CustomCell及其视图仅负责customContentView.layer。
任何人都知道,我做错了什么?
提前致谢!!
答案 0 :(得分:0)
来自描述'委托'属性的CALayer的documentation:'在iOS中,如果图层与UIView对象相关联,则必须将此属性设置为拥有图层的视图。
如果我正确阅读,那么您需要将CustomCellContentView设置为图层委托。将CALayerDelegate中的功能直接移动到您的自定义视图类中,看看是否有效。无论如何,这将是执行此操作的标准方法,而不是仅仅作为代理创建一个单独的类。
答案 1 :(得分:0)
检查您的框架是否不是CGRectZero。
我和你描述的问题有类似的问题。如果框架是CGRectZero,这将阻止调用drawLayer:inContext。