2014-09-19 221 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]。第一個示例包含兩個已關閉的子路徑,但目前第二個示例只包含一個未關閉的路徑。