Reputation: 343
I've been trying/searching for a few days to get this to work to no avail. I'm not sure what I'm missing.
I'm creating a "card" front view and adding to UIView layer. On screen everything looks great, when calling renderInContext one layer will not display.
EDIT: Wanted to add that only the "highlight" gradient layer is not working the other gradient layer is working as expected.
- (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;
And the code to 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];
Upvotes: 1
Views: 1459
Reputation: 3358
Thanks for posting your code, it makes it much easier to help :)
A couple of misunderstandings...
CALayer *cardFrontContainer = [[CALayer layer] init];
This line is wrong. [CALayer layer]
returns a fully formed layer, calling init
is probably doing some 'interesting' things to the layer. In general when you call a class method that returns a new instance (apart from alloc
) you should never call init.
Also this call below in the code will lead to a crash (if it were ever executed, see below).
[cardFrontContainer release]
Since the method layer
does not have 'copy', 'new' or 'alloc' in the name it is returning an object that you should not release. The layer is returned 'autoreleased' and is thus not retained by you.
Please read the ObjC memory management guide here
for more info.
Also, you should listen to the compiler, when it tells you those release calls can't be reached, it means it. After the return
nothing will be executed.
In general you should never put image's into the database, unless they are really small (less than a few dozen kilobytes). Take a look here
for more info on that topic.
As to why it's not drawing the gradient, it could be different color spaces, but that does not appear to be the problem.
I'd say try cleaning up at least the double init
issue and the memory problems then try again.
Upvotes: 4
Reputation: 343
Appears, by luck, I was able to get my problem solved by simply changing the values of my CAGradientLayer colors array.
hightlight.colors = [NSArray arrayWithObjects:(id)[[UIColor whiteColor] CGColor],
(id)[RGBACOLOR(255,255,255, .0) CGColor],
(id)[RGBACOLOR(255,255,255, .0) CGColor], nil];
to
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];
I would have assumed that [UIColor whiteColor] and RGBACOLOR(255,255,255, 1.0) are essentially the same, renderInContext doesn't think so.
Upvotes: 2