I have this quartz class that works fine on iOS and draws an orange pizza slice style graph over a gray circle and I am trying to convert it to cocoa.
+ (UIImage *)circleWithDiameter:(CGFloat) diameter
color:(UIColor *)color
progress:(CGFloat)progress {
CGFloat radius = diameter/2.0f;
CGFloat scale = [[UIScreen mainScreen] scale]; // we need to size the graphics context according to the device scale
CGRect rect = CGRectMake(0.0f, 0.0f, diameter, diameter);
UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale);
CGContextRef context = UIGraphicsGetCurrentContext();
// create a gray circle background
CGContextSetLineWidth(context, 0); // set the line width
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextBeginPath(context);
CGContextAddEllipseInRect(context, rect);
CGContextDrawPath(context, kCGPathFill); // Or kCGPathFill
// Draw the slice
CGFloat angle = progress * 2.0f * M_PI;
CGPoint center = CGPointMake(radius, radius);
CGContextBeginPath(context);
CGContextMoveToPoint(context, center.x, center.y);
CGPoint p1 = CGPointMake(center.x + radius * cosf(angle),
center.y + radius * sinf(angle));
CGContextAddLineToPoint(context, p1.x, p1.y);
CGContextMoveToPoint(context, center.x, center.y);
CGContextAddArc(context, center.x, center.y, radius, 0.0f, angle, 0);
CGContextClosePath(context);
UIColor *orange = [UIColor orangeColor];
CGContextSetFillColorWithColor(context, orange.CGColor);
CGContextDrawPath(context, kCGPathFill);
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
CGContextRelease(context);
return result;
}
This is the class I have converted to cocoa.
+ (NSImage *)circuloWithDiameter:(CGFloat)diameter
color:(NSColor *)color
progress:(CGFloat)progress {
CGFloat radius = diameter/2.0f;
CGContextRef context = [[NSGraphicsContext currentContext] graphicsPort];
// draw the gray circle background
CGContextSetLineWidth(context, 0); // set the line width
CGContextSetFillColorWithColor(context, color.CGColor);
CGContextBeginPath(context);
CGContextAddEllipseInRect(context, rect);
CGContextDrawPath(context, kCGPathFill); // Or kCGPathFill
// draw the orange slice
CGFloat angle = progress * 2.0f * M_PI;
CGPoint center = CGPointMake(radius, radius);
CGContextBeginPath(context);
CGContextMoveToPoint(context, center.x, center.y);
CGPoint p1 = CGPointMake(center.x + radius * cosf(angle),
center.y + radius * sinf(angle));
CGContextAddLineToPoint(context, p1.x, p1.y);
CGContextMoveToPoint(context, center.x, center.y);
CGContextAddArc(context, center.x, center.y, radius, 0.0f, angle, 0);
CGContextClosePath(context);
NSColor *orange = [NSColor orangeColor];
CGContextSetFillColorWithColor(context, orange.CGColor);
CGContextDrawPath(context, kCGPathFill);
CGImageRef imageRef = CGBitmapContextCreateImage(context);
NSImage* result = [[NSImage alloc] initWithCGImage:imageRef size:NSMakeSize(diameter, diameter)];
CFRelease(imageRef);
CGContextRelease(context);
return result;
}
Apparently the conversion goes fine and Xcode is not whining about anything but when the cocoa version runs, it crashes on the line
CGImageRef imageRef = CGBitmapContextCreateImage(context);
with the message
<Error>: CGBitmapContextCreateImage: invalid context 0x600000160180. This is a serious error. This application, or a library it uses, is using an invalid context and is thereby contributing to an overall degradation of system stability and reliability. This notice is a courtesy: please fix this problem. It will become a fatal error in an upcoming update.
what is wrong? any clues?
The process is a little different in AppKit.
First you create an NSImage instance with the desired size. Then you use -[NSImage lockFocus] to initialize the drawing context. This replaces UIKit's UIGraphicsBeginImageContextWithOptions function.
From this point, your drawing code is the same as UIKit, using [[NSGraphicsContext currentContext] graphicsPort] to get the current CGContextRef.
When you finish drawing, use -[NSImage unlockFocus] to dispose of the current CGContextRef. You can then return the NSImage instance you created at the start of the function.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With