填充方法在不同类型的UIBezierPath中的奇怪行为

时间:2014-09-19 11:30:53

标签: ios objective-c core-graphics uibezierpath

我一直在尝试两种形状。第一个是一种框架,其代码如下:

((x,y)是我UIView的起源,(w,h)是它的大小)

[bpath moveToPoint:CGPointMake(x, y)];
[bpath addLineToPoint:CGPointMake(x + w, y)];
[bpath addLineToPoint:CGPointMake(x + w, y + h)];
[bpath addLineToPoint:CGPointMake(x, y + h)];
[bpath closePath];

[bpath moveToPoint:CGPointMake(x + 100, y + 100)];
[bpath addLineToPoint:CGPointMake(x + 100, y + 50)];
[bpath addLineToPoint:CGPointMake(x + 50, y + 50)];
[bpath addLineToPoint:CGPointMake(x + 50, y + 100)];
[bpath closePath];

这给了我以下输出:

第二个是圆圈内的圆圈。其代码如下:

[bpath moveToPoint:CGPointMake(x + w, y + h * 0.5)];
[bpath addArcWithCenter:CGPointMake(x + w * 0.5, y + h * 0.5) radius:midx startAngle:0 endAngle:2 * M_PI clockwise:YES];

[bpath moveToPoint:CGPointMake(x + w * 0.75, y + h * 0.5)];
[bpath addArcWithCenter:CGPointMake(x + w * 0.5, y + h * 0.5) radius:0.25 * w startAngle:0 endAngle:2 * M_PI clockwise:YES];

为此,我得到了类似下面的内容:

enter image description here

我将[bpath fill]应用于两个路径。那么为什么填充模式存在差异呢? (我尝试在第二种情况下添加closePath,但它没有任何区别)。

另外,有没有办法获得与第一个形状相似的填充图案? (我知道可以通过为内圈添加第二条路径来完成,但我想在一条路径中完成)

更新:我注意到如果我在第二条路径上使用containsPoint,当触摸点位于内部圆圈内时,它会返回FALSE,并且仅在TRUE时返回{{1}}触摸点位于两个圆圈之间。第一种形状也表现出类似的行为。

2 个答案:

答案 0 :(得分:3)

要让第二个示例创建一个洞,您需要设置usesEvenOddFillRule

bpath.usesEvenOddFillRule = YES;
[bpath fill];

这是我的工作代码:

UIBezierPath *bpath = [UIBezierPath bezierPath];
CGFloat x = rect.origin.x;
CGFloat y = rect.origin.y;
CGFloat w = rect.size.width;
CGFloat h = rect.size.height;
CGFloat midx = (x + w) / 2;

[bpath moveToPoint:CGPointMake(x + w, y + h * 0.5)];
[bpath addArcWithCenter:CGPointMake(x + w * 0.5, y + h * 0.5) radius:midx startAngle:0 endAngle:2 * M_PI clockwise:YES];

[bpath moveToPoint:CGPointMake(x + w * 0.75, y + h * 0.5)];
[bpath addArcWithCenter:CGPointMake(x + w * 0.5, y + h * 0.5) radius:0.25 * w startAngle:0 endAngle:2 * M_PI clockwise:YES];

[[UIColor blueColor] set];
bpath.usesEvenOddFillRule = YES;
[bpath fill];

结果:

Result image

<强>更新

稍微玩了一下代码之后,我发现了为什么你的第一个例子产生了一个洞而你的第二个例子没有:它是关于路径的方向的!

在第一条路径中,顺时针绘制外部正方形,逆时针绘制内部正方形。这似乎使填充的零规则考虑内部矩形为&#34;外部&#34;。

但圆圈都是朝同一方向画的。如果您反转内圈的方向,即使没有设置usesEvenOddFillRule也会打洞:

[bpath addArcWithCenter:CGPointMake(x + w * 0.5, y + h * 0.5) radius:0.25 * w startAngle:2*M_PI endAngle:0 clockwise:NO];

(请注意,开始和结束角度相反,clockwise:NO)。

答案 1 :(得分:0)

第二个例子也需要[bpath closePath]。第一个示例包含两个已关闭的子路径,但目前第二个示例仅包含一个未关闭的路径。