2014-09-19 219 views
1

我一直在试验两种形状。第一个是一个帧的类型和它的代码如下:不同种类的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。第一种形状也表现出类似的行为。

回答

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

更新:

与代码玩弄一点后,我发现了为什么你的第一个前任充足的产生一个洞,你的第二个没有:这是关于方向的路径!

在第一条路径中,外部正方形按顺时针方向绘制,而内部正方形按逆时针方向绘制。这似乎使填充的零规则认为内部矩形是“外部”的。

但圆圈都在同一个方向绘制。如果颠倒内循环的方向它会让一个孔,即使没有设置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)。

+0

正如我在最后一行中提到的,我已经尝试添加[bpath closePath]并且没有改变。我试过使用EvenOddFillRule,但结果仍然相同。 – blancos 2014-09-19 11:43:26

+0

@blancos:看我的编辑。这对我有用。 – DarkDust 2014-09-19 12:07:09

+0

它的工作。感谢您的解决方案。但仍然想知道第一个形状。我没有为该形状设置使用EvenOddFillRule,但在这种情况下填充模式仍然正确。这种行为的任何原因? – blancos 2014-09-19 12:26:18

0

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