将石英方法从iOS转换为OSX



我有一个石英类,它在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实例。

最新更新