我制作CAShapeLayer的代码是
UIBezierPath *circle = [UIBezierPath bezierPathWithArcCenter:CGPointMake(75, 125)
radius:50
startAngle:0
endAngle:1.8 * M_PI
clockwise:YES];
CAShapeLayer *circleLayer = [CAShapeLayer layer];
[circleLayer setFrame:CGRectMake(200 - 50, 300 - 50, 100, 100)];
circleLayer.path = circle.CGPath;
circleLayer.bounds = CGPathGetBoundingBox(circle.CGPath);
circleLayer.strokeColor = [UIColor colorWithRed:0.4 green:1.0 blue:0.2 alpha:0.5].CGColor;
[circleLayer setFillColor:[UIColor clearColor].CGColor];
circleLayer.lineWidth = 3.0;
if ([circleLayer animationForKey:@"SpinAnimation"] == nil) {
CABasicAnimation* animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation"];
animation.fromValue = [NSNumber numberWithFloat:0.0f];
animation.toValue = [NSNumber numberWithFloat: 2 * M_PI];
animation.duration = 2.0f;
animation.repeatCount = INFINITY;
animation.removedOnCompletion = NO;
[circleLayer addAnimation:animation forKey:@"SpinAnimation"];
}
[self.view.layer addSublayer:circleLayer];
我想制作CAGradientLayer而不是CAShapeLayer。
原因:我需要在图层中使用渐变色,这在CAShapeLayer中是不可能的。
我想在Cirle上使用黄色到黑色渐变。
图片:
在我需要的输出中,从背景图像中提取颜色,并在最后添加一些黑色,或在图层中添加不透明度。
任何想法,建议。
感谢。
答案 0 :(得分:4)
一个快速而肮脏的技巧是添加一个渐变图层作为子图层,然后再添加一些背景颜色与超视图相同的图层(在原始问题中,它是白色的)。
例如:
cornerRadius
)。但是,这可能不适合使用背景图像。
要解决此问题,您可以创建UIView
的自定义子类并覆盖drawRect
方法。
假设存在实例变量:startColor
,endColor
,radius
,strokeWidth
和mirrored
。
变量mirrored
用于控制间隙的位置(切除左侧或右侧)和动画的旋转方向(顺时针或逆时针)。
- (void)drawRect:(CGRect)rect
{
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextSetBlendMode(ctx, kCGBlendModeNormal);
CGFloat gradientColors[4 * 2];
extractColorComponents(_startColor, gradientColors, 0);
extractColorComponents(_endColor, gradientColors, 4);
CGColorSpaceRef baseSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(baseSpace, gradientColors, NULL, 2);
CGColorSpaceRelease(baseSpace);
baseSpace = nil;
CGPoint startPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMinY(rect));
CGPoint endPoint = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));
CGContextDrawLinearGradient(ctx, gradient, startPoint, endPoint, 0);
CGGradientRelease(gradient);
gradient = nil;
// fill 'clear' color
CGContextSetFillColorWithColor(ctx, [UIColor clearColor].CGColor);
CGContextSetStrokeColorWithColor(ctx, [UIColor clearColor].CGColor);
CGContextSetBlendMode(ctx, kCGBlendModeClear);
CGFloat innerCircleRadius = _radius - _strokeWidth;
// fill an 'empty' hole inside the gradient part
CGContextFillEllipseInRect(ctx, (CGRect){
{_strokeWidth, _strokeWidth},
{innerCircleRadius * 2, innerCircleRadius * 2}
});
// fill an 'empty' segment of arc
CGFloat startAngle = _mirrored ? (0.9 * M_PI) : (-0.1 * M_PI);
CGFloat endAngle = startAngle + 0.2 * M_PI;
UIBezierPath *path = [UIBezierPath bezierPathWithArcCenter:(CGPoint){_radius, _radius}
radius:_radius - _strokeWidth * 0.5
startAngle:startAngle
endAngle:endAngle
clockwise:YES];
path.lineWidth = _strokeWidth;
CGContextAddPath(ctx, path.CGPath);
CGContextSetLineWidth(ctx, _strokeWidth + 2);
CGContextStrokePath(ctx);
CGContextSetBlendMode(ctx, kCGBlendModeNormal);
}
此处是视图的complete implementation。
最终结果:
两响:
您可以使用以下代码在viewDidLoad
或其他地方添加两个响铃以获得所需效果:
- (void)viewDidLoad
{
[super viewDidLoad];
UIColor *startColor = [UIColor colorWithHue:0.02 saturation:0.74 brightness:0.91 alpha:1];
UIColor *endColor = [UIColor colorWithHue:0.57 saturation:0.76 brightness:0.86 alpha:1];
CGPoint center = CGPointMake(160, 200);
Spinner *outerSpinner = [[Spinner alloc] initWithCenter:center
radius:50
strokeWidth:3
startColor:startColor
endColor:endColor
mirrored:NO];
Spinner *innerSpinner = [[Spinner alloc] initWithCenter:center
radius:40
strokeWidth:3
startColor:startColor
endColor:endColor
mirrored:YES];
[self.view addSubview:outerSpinner];
[self.view addSubview:innerSpinner];
[outerSpinner startAnimating];
[innerSpinner startAnimating];
}
结果:
答案 1 :(得分:-1)
CALayer上的mask属性使用遮罩层的alpha分量来确定应该可见的内容,而不是。由于您的两种颜色(黑色和白色)都是完全不透明的(没有透明度),因此蒙版无效。要解决此问题,您应该将其中一种颜色更改为清晰的颜色:
gradient.colors = [NSArray arrayWithObjects:(id)[[UIColor blackColor] CGColor],
(id)[[UIColor clearColor] CGColor], nil];
修改强>
class Colors {
let colorTop = UIColor(red: 192.0/255.0, green: 38.0/255.0, blue: 42.0/255.0, alpha: 1.0).CGColor
let colorBottom = UIColor(red: 35.0/255.0, green: 2.0/255.0, blue: 2.0/255.0, alpha: 1.0).CGColor
let gl: CAGradientLayer
init() {
gl = CAGradientLayer()
gl.colors = [ colorTop, colorBottom]
gl.locations = [ 0.0, 1.0]
}
}