我有一个石英类,它在iOS上运行良好,并在灰色圆圈上绘制橙色披萨切片样式的图形,我正在尝试将其转换为可可。
+ (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;
}
这是我转换为可可的类。
+ (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;
}
显然转换正常,Xcode并没有抱怨任何事情,但是当可可版本运行时,它会在线崩溃
CGImageRef imageRef = CGBitmapContextCreateImage(context);
随着消息
<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.
怎么了?有什么线索吗?
AppKit 中略有不同。
首先,创建具有所需大小的NSImage
实例。 然后,使用 -[NSImage lockFocus]
初始化图形上下文。 这取代了UIKit的UIGraphicsBeginImageContextWithOptions
功能。
从这一点来看,您的绘图代码与UIKit相同,使用[[NSGraphicsContext currentContext] graphicsPort]
来获取当前CGContextRef
。
完成绘制后,使用 -[NSImage unlockFocus]
处置当前CGContextRef
。 然后,您可以返回在函数开始时创建的NSImage
实例。