2013-08-25 77 views
2

我想用兩種交替的顏色(例如黑色和白色,認爲Preview.app選擇框)描邊CAShapeLayer的路徑。我不知道如何做到這一點,或者這是否甚至可以使用Quartz。如何用Cocoa中的兩種交替顏色描畫虛線CGPath?

我已經建立了一個CAShapeLayer以具有白色邊框,然後將路徑屬性設置爲黑色虛線。我的希望是,這應該會產生黑色和白色虛線的效果。然而,似乎該路徑被抽中的邊界被撫摸在上面,見截圖(皮毛屬於我的貓),

CAShapeLayer with white border and black stroked path, the path is drawn first followed yb the border.

任何人都可以提出一個更好的方法或方式來獲得這工作?

的代碼,

// Stroke a white border 
[shapeLayer setFrame:shapeRect]; 
[shapeLayer setBorderColor:[[NSColor whiteColor] CGColor]]; 
[shapeLayer setBorderWidth:1.0]; 

// Stroked a black dash path (along the border) 
// and fill shape with clear colour 
[shapeLayer setFillColor:[[NSColor clearColor] CGColor]]; 
[shapeLayer setStrokeColor:[[NSColor blackColor] CGColor]]; 
[shapeLayer setLineWidth:1.0]; 
[shapeLayer setLineJoin:kCALineJoinRound]; 
[shapeLayer setLineDashPattern: 
[NSArray arrayWithObjects:[NSNumber numberWithInt:5], 
    [NSNumber numberWithInt:5], 
    nil]]; 

CGMutablePathRef path = CGPathCreateMutable(); 
CGPathAddRect(path, NULL, shapeLayer.bounds); 
[shapeLayer setPath:path]; 
CGPathRelease(path); 

回答

2

我認爲有兩個問題與該方法(混合層邊界和形狀筆劃)

  1. 邊框是上(邊界)的裏面,但行程從路徑的中心(由)。
  2. 的路徑是由inseting的strokeWidth

    CGFloat halfWidth = 1.0/2.0; 
    CGPathAddRect(path, NULL, CGRectInset(shapeLayer.bounds, halfWidth, halfWidth)); 
    

    路徑一半但是邊境仍在繼續進行上述繪製激起

你可以做一些事情#1後繪製邊框時形狀(至少我不知道如何改變順序)。

我認爲最簡單的解決方案是必須在相同的容器層中形成圖層。容器將被用於改變框架,並且這兩層將被用於繪圖。

底層會有一個白色筆畫(沒有破折號圖案),頂層會有黑色的虛線。由於兩種形狀都具有相同的路徑,所以它看起來像黑色和白色的破折號圖案。

這樣做也可以用於任何形狀。

+0

謝謝。所以在你看來,兩層實際上是唯一的選擇?我試圖遠離它,因爲它感覺像一個黑客! –

+0

@boyfarrell兩層或自定義渲染。我會親自去兩層。我假設你在屏幕上只有少數幾個(如果不是隻有一個)選擇,所以不應該有任何性能影響,並且代碼不是太複雜,並且可以很好地封裝在它自己的類中(對於私有子層) –

+0

是的,這是很好的建議,謝謝。我打算製作一個CAShapeLayer子類(稱爲'HostingShapeLayer'),它具有屬性foregroundLayer。此屬性將前景層添加爲託管圖層的子圖層。託管層還沿着邊界筆觸一條白色路徑。子層可以做到黑色的虛線。聽起來像合理的設計?或者你會去做其他事情? –

0

你有沒有嘗試使用lineDashPhase財產?使用它,您可以先用黑色顯示虛線 - 稍後用相同的路徑更改顏色和lineDashPhase - 以白色顯示。

+0

謝謝。我已經在使用它(用於不同的目的)來做螞蟻行軍,http://www.cimgf.com/2009/10/20/marching-ants-with-core-animation我不知道我遵循你的方式實施會有效嗎?只有一個路徑屬性和一個lineDashPhase屬性,所以我不明白我們如何繪製兩行。 –

+0

對不起,錯過了這一點。但是,您可以添加兩個CAShapeLayers,但我認爲這不是一個好方法。 –

+1

@NickolayOlshevsky你會怎麼做? –