我正在创建一个Apple Watch。所以我在一个Iphone应用程序中使用 UIBezierPath 绘制了一个饼图。我需要将该图转换为 UIImage 。这是我尝试的代码:
GraphView.m
rectImage = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 260)];
CGContextRef context = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(context);
UIGraphicsBeginImageContext(rectImage.frame.size);
CGFloat arcRadious = OUTER_RADIOUS;
CGFloat tmpStartAngle = startAngle;
CGFloat tmpEndAngle = endAngle;
UIBezierPath *path = [[UIBezierPath alloc] init];
path.lineWidth = 23;
[path addArcWithCenter:centre radius:arcRadious startAngle:tmpStartAngle endAngle:tmpEndAngle clockwise:YES];
[(UIColor*)_fillColours[index] setStroke];
[path stroke];
CGContextAddPath(context, path.CGPath);
image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsPopContext();
UIGraphicsEndImageContext();
但在Apple Watch中,只显示了图表的某些部分。谁能告诉我我做错了什么。非常感谢任何帮助。
答案 0 :(得分:2)
CGContextRef context = UIGraphicsGetCurrentContext();
UIGraphicsPushContext(context);
UIGraphicsBeginImageContext(rectImage.frame.size);
我不完全确定你在这里要做什么。
你正在做的是从堆栈顶部获取当前上下文(可能甚至不存在),然后你试图再次将该上下文推送到堆栈 - 这没有任何意义,因为它是已经在堆栈上(这是当前的上下文!)。
然后你要创建你的图像上下文,它会自动将它推到堆栈上 - 使它成为当前的上下文。
因此,我假设你打算做的是:
UIGraphicsBeginImageContext(rectImage.frame.size);
CGContextRef context = UIGraphicsGetCurrentContext();
这将创建一个新的图像上下文,使其成为当前上下文,然后获取对它的引用。
UIBezierPath *path = [[UIBezierPath alloc] init];
[path addArcWithCenter:centre radius:arcRadious startAngle:tmpStartAngle endAngle:tmpEndAngle clockwise:YES];
这可能会有问题,因为在添加弧之前从未将路径移动到某个点 - 因此可能无法正确绘制。
因此,您需要在添加之前将其移动到圆弧的中心点。
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:centre];
[path addArcWithCenter:centre radius:arcRadious startAngle:tmpStartAngle endAngle:tmpEndAngle clockwise:YES];
[(UIColor*)_fillColours[index] setStroke];
[path stroke];
CGContextAddPath(context, path.CGPath); // <- Remove
这里的第三行是不必要的。这是因为stroke
上的UIBezierPath
方法实际上将贝塞尔路径添加到当前上下文,然后在该上下文中描绘路径。
UIGraphicsPopContext(); // <- Remove
UIGraphicsEndImageContext();
同样,当您调用UIGraphicsEndImageContext()
时,图像上下文将处理从堆栈中弹出的内容,因此尝试自行弹出可能会导致问题。
rectImage = [[UIView alloc] initWithFrame:CGRectMake(0, 0, 300, 260)];
看到您在此代码中处理图片时,名称rectImage
相当误导,因为它是UIView
。我会重命名为rectView
。
CGFloat arcRadious = OUTER_RADIOUS;
我真诚地希望OUTER_RADIOUS
不是宏(#define
)。常量不应该用宏定义 - 它们不是类型安全的,可以使调试变成一场噩梦。像瘟疫一样避免它们。
相反,您应该使用static
C常量。例如:
static CGFloat const kOuterRadius = 100.0