将Quartz方法从iOS转换为OSX

Spa*_*Dog 4 macos cocoa cocoa-touch quartz-graphics ios

我有这个石英类在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;

}
Run Code Online (Sandbox Code Playgroud)

这是我转换为可可的类.

+ (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;

}
Run Code Online (Sandbox Code Playgroud)

显然转换很顺利,Xcode并没有抱怨任何东西,但是当可可版本运行时,它崩溃就行了

  CGImageRef imageRef = CGBitmapContextCreateImage(context);
Run Code Online (Sandbox Code Playgroud)

随着消息

<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.
Run Code Online (Sandbox Code Playgroud)

怎么了?任何线索?

Dar*_*ren 8

这个过程在AppKit中有点不同.

首先,创建一个NSImage具有所需大小的实例.然后-[NSImage lockFocus]用于初始化绘图上下文.这取代了UIKit的UIGraphicsBeginImageContextWithOptions功能.

从这一点来说,您的绘图代码与UIKit相同,[[NSGraphicsContext currentContext] graphicsPort]用于获取当前的代码CGContextRef.

完成绘图后,使用-[NSImage unlockFocus]处理电流CGContextRef.然后,您可以返回NSImage在函数开头创建的实例.