CAGradientLayer在renderInContext中消失

时间:2011-03-24 19:11:12

标签: objective-c calayer

我一直在尝试/搜索几天让这个工作无济于事。我不确定我错过了什么。

我正在创建一个“卡片”前视图并添加到UIView图层。在屏幕上,一切看起来都很棒,当调用renderInContext时,一个图层将不会显示。

编辑:想要添加只有“突出显示”渐变图层不起作用,其他渐变图层正在按预期工作。

- (CALayer *)createCardFront {

NSLog(@"Card createCardFront Called");

// Create the layers we want to use

CALayer *cardFrontContainer = [CALayer layer];
CALayer *processedImage = [CALayer layer];
CAGradientLayer *gradient = [CAGradientLayer layer];
CAGradientLayer *hightlight = [CAGradientLayer layer];
CALayer *icon = [CALayer layer];
CAShapeLayer *gloss = [CAShapeLayer layer];

// Position them correctly

[cardFrontContainer addSublayer:processedImage];
[cardFrontContainer addSublayer:gradient];
[cardFrontContainer addSublayer:hightlight];
[cardFrontContainer addSublayer:icon];
[cardFrontContainer addSublayer:gloss];


// Base size for card

CGRect rect = CGRectMake(0., 0., (200. * [cardScale floatValue]), (276. * [cardScale floatValue]));

// Container Properties

cardFrontContainer.bounds = rect;
cardFrontContainer.position = CGPointMake((frontView.center.x * [cardScale floatValue]), (138. * [cardScale floatValue])-10);
cardFrontContainer.cornerRadius = (25. * [cardScale floatValue]);
cardFrontContainer.masksToBounds = YES;
cardFrontContainer.borderWidth = .5;
cardFrontContainer.borderColor = [RGBACOLOR(120,120,120, .7) CGColor];
[cardFrontContainer setNeedsDisplay];

// Highlight Properites

hightlight.bounds = rect;
hightlight.position = CGPointMake((100. * [cardScale floatValue]), (138. * [cardScale floatValue]));
hightlight.startPoint = CGPointMake(0., 0.0);
hightlight.endPoint = CGPointMake(0., 1.);
hightlight.opacity = 1.;
hightlight.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:.0111],
                        [NSNumber numberWithFloat:.0999],
                        [NSNumber numberWithFloat:1.], nil];

hightlight.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor],
                     (id)[RGBACOLOR(255,255,255, .0) CGColor],
                     (id)[RGBACOLOR(255,255,255, .0) CGColor], nil];


// Gradient Properites

gradient.bounds = rect;
gradient.position = CGPointMake((100. * [cardScale floatValue]), (138. * [cardScale floatValue]));
gradient.startPoint = CGPointMake(0, 0.5);
gradient.endPoint = CGPointMake(1.0, 0.5);
gradient.opacity = 1.;
gradient.locations = [NSArray arrayWithObjects:[NSNumber numberWithFloat:.0111],
                            [NSNumber numberWithFloat:.099],
                            [NSNumber numberWithFloat:.899],
                            [NSNumber numberWithFloat:.9999], nil];

gradient.colors = [NSArray arrayWithObjects:(id)[RGBACOLOR(0,0,0, .3) CGColor],
                         (id)[[UIColor clearColor] CGColor],
                         (id)[[UIColor clearColor] CGColor],
                         (id)[RGBACOLOR(0,0,0, .3) CGColor], nil];



// Background Properites

processedImage.bounds = rect;
processedImage.position = CGPointMake((100. * [cardScale floatValue]), (138. * [cardScale floatValue]));
processedImage.contents = (id)[cachedBackground CGImage];


// Icon Properites

iconImage = [[self processThumbnailImageForLayer] retain];

icon.bounds = CGRectMake(0., 0., (200 * [cardScale floatValue]), (276 * [cardScale floatValue]));
icon.position = CGPointMake((100. * [cardScale floatValue]), (138. * [cardScale floatValue]));
icon.contents = (id)[iconImage CGImage];



// Set the Gloss Layer

gloss.frame = CGRectMake(0., 0., (200. * [cardScale floatValue]), (200. * [cardScale floatValue]));
gloss.position = CGPointMake(0.,0.);
CGMutablePathRef thePath = CGPathCreateMutable();
CGPathMoveToPoint(thePath,NULL,(100. * [cardScale floatValue]),(350. * [cardScale floatValue]));
CGPathAddLineToPoint(thePath, NULL, (100. * [cardScale floatValue]), (100. * [cardScale floatValue]));
CGPathAddLineToPoint(thePath, NULL, (270. * [cardScale floatValue]), (100. * [cardScale floatValue]));
CGPathAddCurveToPoint(thePath,NULL,
                      (200. * [cardScale floatValue]),(140. * [cardScale floatValue]),
                      (100. * [cardScale floatValue]),(245. * [cardScale floatValue]),
                      (100. * [cardScale floatValue]),(376. * [cardScale floatValue]));
CGPathCloseSubpath(thePath);
gloss.path = thePath;
CGPathRelease(thePath);
gloss.opacity = .3;
gloss.fillColor = [[UIColor whiteColor] CGColor];


return cardFrontContainer;

renderInContext的代码:

- (void) imageFromView {

NSLog(@"Card imageFromView Called");

NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];



UIGraphicsBeginImageContext(CGSizeMake(170., 238.));
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

NSData *imageData = UIImagePNGRepresentation (viewImage);

// Add to core data object

attributeObject.cardCache = imageData;
attributeObject.shouldUpdateCard = NO;

[self saveAction];

[self.managedObjectContext reset];
 self.managedObjectContext = nil;

[pool release];

2 个答案:

答案 0 :(得分:4)

感谢发布您的代码,这使得帮助更容易:)

一些误解......

CALayer *cardFrontContainer = [[CALayer layer] init];

这条线错了。 [CALayer layer]返回一个完全形成的图层,调用init可能会对图层做一些“有趣”的事情。通常,当您调用返回新实例的类方法时(除alloc之外),您永远不应该调用init。

此代码中的此调用也会导致崩溃(如果执行过,请参阅下文)。

[cardFrontContainer release]

由于方法layer在名称中没有'copy','new'或'alloc',因此它返回一个你不应该释放的对象。该图层将被“自动释放”,因此不会被您保留。

请阅读ObjC内存管理指南here

了解更多信息。

另外,你应该听编译器,当它告诉你那些释放调用无法到达时,就意味着它。 return之后将不会执行任何操作。

一般情况下,您不应该将图像放入数据库,除非它们非常小(少于几十千字节)。看看here

有关该主题的更多信息。

至于为什么它没有绘制渐变,它可能是不同的颜色空间,但这似乎不是问题。

我会说尝试至少清理双init问题和内存问题,然后重试。

答案 1 :(得分:2)

幸运的是,通过简单地更改我的CAGradientLayer颜色数组的值,我能够解决问题。

hightlight.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor],
                 (id)[RGBACOLOR(255,255,255, .0) CGColor],
                 (id)[RGBACOLOR(255,255,255, .0) CGColor], nil];

hightlight.colors = [NSArray arrayWithObjects:(id)[RGBACOLOR(255,255,255, 1.0) CGColor],
                 (id)[RGBACOLOR(255,255,255, .0) CGColor],
                 (id)[RGBACOLOR(255,255,255, .0) CGColor], nil];

我原本假设[UIColor whiteColor]和RGBACOLOR(255,255,255,1.0)基本相同,renderInContext不这么认为。