用一种颜色绘制多边形的轮廓,用不同的颜色填充它,应该怎么做?

8

我在绘制一些用颜色描边的线条并填充它们的内部(它们形成一个多边形)时遇到了问题。

UIColor *houseBorderColor = [UIColor colorWithRed:(170/255.0) green:(138/255.0) blue:(99/255.0) alpha:1];
CGContextSetStrokeColorWithColor(context, houseBorderColor.CGColor);
CGContextSetLineWidth(context, 3);

// Draw the polygon
CGContextMoveToPoint(context, 20, viewHeight-19.5);
CGContextAddLineToPoint(context, 200, viewHeight-19.5); // base
CGContextAddLineToPoint(context, 300, viewHeight-119.5); // right border
CGContextAddLineToPoint(context, 120, viewHeight-119.5);
CGContextAddLineToPoint(context, 20, viewHeight-19.5);

// Fill it
CGContextSetRGBFillColor(context, (248/255.0), (222/255.0), (173/255.0), 1);
//CGContextFillPath(context);

// Stroke it
CGContextStrokePath(context);

没有注释CGContextStrokePath,我得到了这个结果:

enter image description here

但是如果我取消注释CGContextStrokePath并填充多边形,颜色会溢出笔画:

enter image description here

如何获得像这样的结果(而无需重复整个绘图过程):

enter image description here

3个回答

19

您可以使用

CGContextDrawPath(context, kCGPathFillStroke);

代替

CGContextFillPath(context);
CGContextStrokePath(context);
问题在于CGContextFillPath()CGContextStrokePath(context)都会清除当前路径,因此只有第一个操作成功,第二个操作不会绘制任何东西。CGContextDrawPath()将填充和描边组合在一起,而不清除路径之间的内容。

我不想显得苛求,但您能否详细说明一下,以便回答更加完整,因为我不太明白 CGContextDrawPath() 应该放在哪里? - Morgan Wilde
3
抱歉,我的回答很简短,因为我正在通话中 :-) 这个电话替代了CGContextFillPath和...StrokePath。 - Martin R
这是在这种情况下最好的解决方案。 - al45tair
(翻白眼。)当然……使用DrawPath,而不是FillPath或StrokePath。里面有(苹果)的逻辑!谢谢你的提示……我也遇到了同样的问题。 - Mike Gledhill

5
使用UIBezierPath可以实现这个效果:
UIBezierPath *path = [[UIBezierPath alloc] init];
[path moveToPoint:CGPointMake(20, viewHeight-19.5)];
[path addLineToPoint:CGPointMake(200, viewHeight-19.5)];
[path addLineToPoint:CGPointMake(300, viewHeight-119.5)];
[path addLineToPoint:CGPointMake(120, viewHeight-119.5)];
[path addLineToPoint:CGPointMake(20, viewHeight-19.5)];

[[UIColor colorWithRed:(248/255.0) green:(222/255.0) blue:(173/255.0) alpha:1.0] setFill];
[path fill];
[[UIColor colorWithRed:(170/255.0) green:(138/255.0) blue:(99/255.0) alpha:1.0] setStroke];
[path stroke];

我只从苹果的例子中了解过UIBezierPath,与我问题中提到的CGContext方法相比,它有什么优点吗?@MikePollard - Morgan Wilde
2
我认为使用NSObjects而不是Core Foundation对象的所有通常优点。 - Mike Pollard

2
当您在上下文中描边或填充路径时,上下文会自动删除该路径(因为它认为自己的工作已经完成)。如果您想在描边后填充路径,则必须再次添加该路径。
最好创建一个局部变量CGPathRef path,构建路径,添加它,描边,再次添加它,然后填充。
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, 20, viewHeight-19.5);
CGPathAddLineToPoint(path nil, 200, viewHeight-19.5); // base
CGPathAddLineToPoint(path nil, 300, viewHeight-119.5); // right border
CGPathAddLineToPoint(path nil, 120, viewHeight-119.5);
CGPathAddLineToPoint(path nil, 20, viewHeight-19.5);

CGContextAddPath(context, path);
CGContextFillPath(context);

// possibly modify the path here if you need to

CGContextAddPath(context, path);
CGContextStrokePath(context);

您能否详细说明使用我提供的代码创建“路径”? - Morgan Wilde
1
你应该使用CGPath API而不是CGContext来创建路径。然而,在这种情况下,你应该使用CGContextDrawPath(),因为你遇到的问题确实是由于CGContextFillPath()将路径从上下文中移除(所以你正在描绘一个空路径,这就是为什么没有任何事情发生的原因)。 - al45tair
非常感谢您抽出时间解释这个概念,这让CGContext的相关内容更加清晰易懂!谢谢! - Morgan Wilde

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接