2011-01-19 34 views
29

Có ai có kinh nghiệm trong việc áp dụng Gradient cho CAShapeLayer không? CAShapeLayer là một lớp lớp tuyệt vời, nhưng nó dường như chỉ hỗ trợ màu tô đầy, trong khi tôi muốn nó có một gradient điền (thực sự là một gradient animatable lúc đó).Áp dụng Gradient cho CAShapeLayer

Mọi thứ khác cần làm với CAShapeLayer (bóng, hình dạng, màu nét, đường dẫn hình động) là điều tuyệt vời.

Tôi đã thử đặt một CAGradientLayer bên trong một CAShapeLayer, hoặc thực sự đặt CAShapeLayer làm mặt nạ của GradientLayer và thêm cả hai vào một lớp chứa, nhưng chúng không có kết quả đúng.

Tôi có nên phân lớp CAShapeLayer hoặc có cách nào tốt hơn không?

Cảm ơn.

+0

Tôi tin [câu hỏi này] (http://stackoverflow.com/questions/1303855/how-to-draw-a-gradient-line-fading-in-out-with-core-graphics-iphone) chứa [câu trả lời của Matt Long] (http://stackoverflow.com/questions/1303855/how-to-draw-a-gradient-line-fading-in-out-with-core-graphics-iphone/1303943# 1303943). – Palimondo

Trả lời

53

Bạn có thể sử dụng đường dẫn của hình dạng của bạn để tạo ra một lớp mặt nạ và áp dụng mà trên lớp gradient, như thế này:

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]; 

Nếu bạn muốn sử dụng bóng tối, bạn sẽ phải đặt một "trùng lặp" của lớp hình dạng dưới lớp gradient, tái chế cùng một tham chiếu đường dẫn.

+2

Đây là một câu trả lời tuyệt vời. Đối với những người không nhận thức được điều này (như tôi), tôi muốn thêm rằng bạn có thể thêm mặt nạ, gradient, bóng và bất kỳ lớp nào khác mà bạn có thể cần đến lớp Container ('CALayer container = [Lớp CALayer] ') và sau đó chỉ phải quản lý lớp chứa đó nếu bạn cần tạo hiệu ứng vị trí của nó. –

+0

Câu trả lời hay! Cảm ơn bạn! – user5685969

2

Đây là một giải pháp tuyệt vời, nhưng bạn có thể gặp phải các sự cố không mong muốn nếu bạn tạo danh mục trên CAShapeLayer nơi bạn không có chế độ xem ngay lập tức.

Xem Setting correct frame of a newly created CAShapeLayer

Bottom line, có được bờ cõi của các con đường sau đó thiết lập khung gradient mặt nạ bằng cách sử dụng các giới hạn đường dẫn và dịch khi cần thiết. Điều tốt ở đây là bằng cách sử dụng giới hạn của đường dẫn hơn là bất kỳ khung nào khác, gradient sẽ chỉ vừa với đường giới hạn (giả sử đó là những gì bạn muốn).

// 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]; 
Các vấn đề liên quan