CAGradientLayer当renderInContext正在消失

问题描述:

我一直在努力/搜索几天才得到这个工作无济于事。我不确定我错过了什么。CAGradientLayer当renderInContext正在消失

我创建一个“卡”前视图并添加到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]; 
+0

如果locations数组包含的值超出[0,1],则不会使用renderInContext进行渲染。 – 2012-12-03 23:21:51

感谢张贴你的代码,这使得它更容易帮助:)

一对夫妇的误解......

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

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

此代码下面的这个调用将导致崩溃(如果它曾经被执行过,见下文)。

[cardFrontContainer release] 

由于layer没有在名称中“复制”,“新”或“页头”的方法,它返回一个对象,你不应该释放。该图层返回'autoreleased',因此不会被您保留。

请阅读ObjC内存管理指南here

获取更多信息。

此外,你应该听编译器,当它告诉你那些释放调用无法到达时,它意味着它。 return之后什么都不会执行。

一般来说,除非它们非常小(少于几十千字节),否则不应该将图像放入数据库中。看看here

有关该主题的更多信息。

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

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

+0

感谢您的反馈意见。我已经根据你的建议进行了更新,但就我的问题而言,它没有什么不同,但是,可能会导致一些问题。正在存储的图像非常小,为23kb。谢谢 – downed 2011-03-24 20:27:23

出现,幸运的是,我能够通过简单地更改我的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并不这么认为。

+0

这是问题,如上所述,不同的颜色空间(我应该注意到...)[UIColor whiteColor]和[UIColor blackColor]在灰色空间中 – 2011-03-24 20:52:52