【问题标题】:Drawing multiple arcs using Core Graphics使用 Core Graphics 绘制多条弧线
【发布时间】:2013-08-14 20:50:08
【问题描述】:

我正在尝试使用 Core Graphics 绘制两个同心圆。我希望下面的代码在里面绘制一个蓝色圆圈和一个较小的白色圆圈,但是它只绘制蓝色圆圈。我错过了什么?

CGContextRef c = UIGraphicsGetCurrentContext();

CGContextAddArc(c, self.bounds.size.width/2, self.bounds.size.height/2, 100, 0, M_PI * 2, true);
CGContextSetFillColor(c, CGColorGetComponents([[UIColor blueColor] CGColor]));
CGContextFillPath(c);

CGContextAddArc(c, self.bounds.size.width/2, self.bounds.size.height/2, 90, 0, M_PI * 2, true);
CGContextSetFillColor(c, CGColorGetComponents([[UIColor whiteColor] CGColor]));
CGContextFillPath(c);

【问题讨论】:

    标签: core-graphics


    【解决方案1】:

    您正在以不必要的间接方式设置填充颜色。改为这样做:

    CGContextAddArc(c, self.bounds.size.width/2, self.bounds.size.height/2, 100, 0, M_PI * 2, true);
    CGContextSetFillColorWithColor(c, [[UIColor blueColor] CGColor]);
    CGContextFillPath(c);
    
    CGContextAddArc(c, self.bounds.size.width/2, self.bounds.size.height/2, 90, 0, M_PI * 2, true);
    CGContextSetFillColorWithColor(c, [[UIColor whiteColor] CGColor]);
    CGContextFillPath(c);
    

    或者,更好的是,直接使用 UIKit 的绘图方法:

    [[UIColor blueColor] setFill];
    [[UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:100 startAngle:0 endAngle:M_PI * 2 clockwise:YES] fill];
    
    [[UIColor whiteColor] setFill];
    [[UIBezierPath bezierPathWithArcCenter:CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2) radius:90 startAngle:0 endAngle:M_PI * 2 clockwise:YES] fill];
    

    您的代码失败了,因为[[UIColor whiteColor] CGColor] 在“灰色”颜色空间中返回一种颜色,该颜色空间只有两个分量,一个“灰色”值(0 代表黑色,1 代表白色)和一个 alpha 值。在本例中,上下文是 RGBA,因此CGContextSetFillColor 预计会看到 4 个分量,三个用于 RGB,一个用于 alpha。

    The documentation for CGContextSetFillColor指出:

    请注意,现在要使用的首选 API CGContextSetFillColorWithColor.

    【讨论】:

    • “上下文是 RGBA”有点误导;上下文用于支持的颜色空间并不重要,重要的是它的fill color space 是什么。没有提到默认值;对于全新的上下文,它可能是 RGB 或上下文的背景颜色空间(通常是 RGB),但使用SetFillColorWithColorSetRGBFillColor 等设置填充颜色会将填充颜色空间设置为副作用.
    • ... 因此,例如,如果您要 SetFillColorWithColor 一个白色,那么填充颜色空间将是一个白色空间,而 SetFillColor 将只期望一个或两个组件 - 甚至如果上下文的背景是 RGB。
    • @PeterHosey:完全正确,对于 iOS 或 Mac 应用程序中最常见的情况,我过于简单化了。在多年使用 CG 的过程中,我不能说我曾经担心过填充颜色空间。也许我只是幸运。
    • 它出现在 a coupletimes before 中,但是是的,它非常罕见。