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];
感谢张贴你的代码,这使得它更容易帮助:)
一对夫妇的误解......
CALayer *cardFrontContainer = [[CALayer layer] init];
这条线是错误的。 [CALayer layer]
返回完全形成的图层,调用init
可能会为图层做一些“有趣”的事情。通常,当你调用一个返回新实例的类方法时(除了alloc
),你不应该调用init。
此代码下面的这个调用将导致崩溃(如果它曾经被执行过,见下文)。
[cardFrontContainer release]
由于layer
没有在名称中“复制”,“新”或“页头”的方法,它返回一个对象,你不应该释放。该图层返回'autoreleased',因此不会被您保留。
请阅读ObjC内存管理指南here
获取更多信息。
此外,你应该听编译器,当它告诉你那些释放调用无法到达时,它意味着它。 return
之后什么都不会执行。
一般来说,除非它们非常小(少于几十千字节),否则不应该将图像放入数据库中。看看here
有关该主题的更多信息。
至于为什么不绘制渐变,它可能是不同的颜色空间,但这似乎不是问题。
我会说试试清理至少双重init
问题和内存问题,然后再试一次。
感谢您的反馈意见。我已经根据你的建议进行了更新,但就我的问题而言,它没有什么不同,但是,可能会导致一些问题。正在存储的图像非常小,为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并不这么认为。
这是问题,如上所述,不同的颜色空间(我应该注意到...)[UIColor whiteColor]和[UIColor blackColor]在灰色空间中 – 2011-03-24 20:52:52
如果locations数组包含的值超出[0,1],则不会使用renderInContext进行渲染。 – 2012-12-03 23:21:51