2011-01-19 66 views
29

有沒有人將漸變應用於CAShapeLayer? CAShapeLayer是一個夢幻般的圖層類,但它似乎只支持實心填充着色,而我希望它有一個漸變填充(實際上是一個可生成動畫的漸變)。將漸變應用於CAShapeLayer

與CAShapeLayer(陰影,形狀,描邊顏色,動畫形狀路徑)有關的其他一切都很棒。

我已經嘗試將一個CagradientLayer放置在CAShapeLayer中,或者確實將CAShapeLayer設置爲GradientLayer的掩碼並將它們添加到容器圖層,但這些都沒有正確的結果。

我應該繼承CAShapeLayer,還是有更好的方法呢?

謝謝。

+0

我相信[這個問題](http://stackoverflow.com/questions/1303855/how-to-draw-a-gradient-line-fading-in-out-with-core-graphics-iphone )包含[Matt Long的答案](http://stackoverflow.com/questions/1303855/how-to-draw-a-gradient-line-fading-in-out-with-core-graphics-iphone/1303943# 1303943)。 – Palimondo 2011-08-18 10:26:58

回答

53

你可以使用你的形狀的路徑來創建一個屏蔽層,並應用了漸變層上,像這樣:

UIView *v = [[UIView alloc] initWithFrame:self.window.frame]; 

CAShapeLayer *gradientMask = [CAShapeLayer layer]; 
gradientMask.fillColor = [[UIColor clearColor] CGColor]; 
gradientMask.strokeColor = [[UIColor blackColor] CGColor]; 
gradientMask.lineWidth = 4; 
gradientMask.frame = CGRectMake(0, 0, v.bounds.size.width, v.bounds.size.height); 

CGMutablePathRef t = CGPathCreateMutable();  
CGPathMoveToPoint(t, NULL, 0, 0); 
CGPathAddLineToPoint(t, NULL, v.bounds.size.width, v.bounds.size.height); 

gradientMask.path = t; 


CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 
gradientLayer.startPoint = CGPointMake(0.5,1.0); 
gradientLayer.endPoint = CGPointMake(0.5,0.0); 
gradientLayer.frame = CGRectMake(0, 0, v.bounds.size.width, v.bounds.size.height); 
NSMutableArray *colors = [NSMutableArray array]; 
for (int i = 0; i < 10; i++) { 
    [colors addObject:(id)[[UIColor colorWithHue:(0.1 * i) saturation:1 brightness:.8 alpha:1] CGColor]]; 
} 
gradientLayer.colors = colors; 

[gradientLayer setMask:gradientMask]; 
[v.layer addSublayer:gradientLayer]; 

如果你也想使用陰影,你將不得不放置在漸變圖層下面的「形狀圖層」的「重複」,循環使用相同的路徑引用。

+2

這是一個了不起的答案。 對於那些沒有意識到這一點的人(比如我),我想補充一點,您可以將遮罩,漸變,陰影和其他可能需要的圖層添加到Container圖層(CALayer容器= [CALayer圖層] `),然後只需要管理該容器層,如果您需要動畫的位置。 – 2013-08-29 23:52:58

2

這是一個很好的解決方案,但是如果您在CAShapeLayer上創建了一個您沒有立即擁有視圖的類別,您可能會遇到意想不到的問題。

Setting correct frame of a newly created CAShapeLayer

底線,獲取路徑的邊界,然後使用路徑邊界和視需要翻譯設置漸變蒙版的框架。這裏的好處是,通過使用路徑邊界而不是其他任何框架,梯度將僅適用於路徑邊界內(假設這是您想要的)。

// Category on CAShapeLayer 

CGRect pathBounds = CGPathGetBoundingBox(self.path); 

CAShapeLayer *gradientMask = [CAShapeLayer layer]; 
gradientMask.fillColor = [[UIColor blackColor] CGColor]; 
gradientMask.frame = CGRectMake(0, 0, pathBounds.size.width, pathBounds.size.height); 
gradientMask.path = self.path; 

CAGradientLayer *gradientLayer = [CAGradientLayer layer]; 
gradientLayer.startPoint = CGPointMake(0.5,1.0); 
gradientLayer.endPoint = CGPointMake(0.5,0.0); 
gradientLayer.frame = CGRectMake(0, 0, pathBounds.size.width, pathBounds.size.height); 

NSMutableArray *colors = [NSMutableArray array]; 
for (int i = 0; i < 10; i++) { 
    [colors addObject:(id)[[UIColor colorWithHue:(0.1 * i) saturation:1 brightness:.8 alpha:1] CGColor]]; 
} 
gradientLayer.colors = colors; 

[gradientLayer setMask:gradientMask]; 
[self addSublayer:gradientLayer];