Как нарисовать дугу с изогнутым краем в iOS?
В одном из моих приложений я пытаюсь нарисовать дугу градиента с закругленными краями. Как на следующем рисунке.
Это то, что я сделал до сих пор, используя следующий код.
-(void)startArc
{
UIBezierPath *roundedArc = [self arcWithRoundedCornerAt:centerPoint startAngle:DEGREES_TO_RADIANS(-90) endAngle:DEGREES_TO_RADIANS(90) innerRadius:width-20 outerRadius:width cornerRadius:0];
CAShapeLayer *mask = [CAShapeLayer new];
[mask setPath:roundedArc.CGPath];
[mask setFrame:_outerView.bounds];
[mask setShouldRasterize:YES];
[mask setRasterizationScale:[UIScreen mainScreen].scale];
CAGradientLayer *gradient = [CAGradientLayer new];
[gradient setFrame:_outerView.bounds];
// [gradient setColors:[NSArray arrayWithObjects:(id)[[UIColor colorWithRed:0.86 green:0.91 blue:0.96 alpha:1.0f] CGColor],(id)[[UIColor colorWithRed:0.98 green:0.99 blue:0.99 alpha:1.0f] CGColor], nil]];
[gradient setColors:[NSArray arrayWithObjects:(id)[UIColor colorWithRed:0.19 green:0.64 blue:0.89 alpha:1.0].CGColor,(id)[UIColor colorWithRed:0.14 green:0.76 blue:0.56 alpha:1.0f].CGColor, nil]];
[gradient setMask:mask];
[_outerView.layer addSublayer:gradient];
}
- (UIBezierPath *)arcWithRoundedCornerAt:(CGPoint)center
startAngle:(CGFloat)startAngle
endAngle:(CGFloat)endAngle
innerRadius:(CGFloat)innerRadius
outerRadius:(CGFloat)outerRadius
cornerRadius:(CGFloat)cornerRadius
{
CGFloat innerTheta = asin(cornerRadius / 2.0 / (innerRadius + cornerRadius)) * 2.0;
CGFloat outerTheta = asin(cornerRadius / 2.0 / (outerRadius - cornerRadius)) * 2.0;
UIBezierPath *path = [UIBezierPath bezierPath];
[path addArcWithCenter:center
radius:innerRadius + cornerRadius
startAngle:endAngle - innerTheta
endAngle:startAngle + innerTheta
clockwise:false];
[path addArcWithCenter:center
radius:outerRadius - cornerRadius
startAngle:startAngle + outerTheta
endAngle:endAngle - outerTheta
clockwise:true];
[path closePath];
return path;
}
С помощью вышеуказанного кода я добился следующего
Может ли кто-нибудь дать мне знать о том, как достичь этих закругленных краев ? Тот, который я реализовал, имеет острые края.
1 ответ:
Вероятно, самый простой подход:
- Создайте один путь дуги (вдоль середины целевой дуги) в виде пути
- Установите ширину линии (20 в вашем случае) и заглушку линии (закругленные заглушки)
- преобразование пути в гладкий путь (CGContextReplacePathWithStrokedPath)
- Продолжайте с вашим существующим кодом для градиента
Поглаживание преобразует ваш 90-градусный дуговой путь, который бесконечно узок, в контур линии, которая является 20 пикселей в ширину и имеет закругленные концы линий.
Код может приблизительно выглядеть так:
- (UIBezierPath *)arcWithRoundedCornerAt:(CGPoint)center startAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle innerRadius:(CGFloat)innerRadius outerRadius:(CGFloat)outerRadius cornerRadius:(CGFloat)cornerRadius context:(CGContext)context { CGFloat radius = (innerRadius + outerRadius) / 2.0; CGContextAddArc(context, center.x, center.y, radius, startAngle, endAngle, true); CGContextSetLineCap(context, kCGLineCapRound); CGContextSetLineWidth(context, outerRadius - innerRadius); CGContextReplacePathWithStrokedPath(context) return [UIBezierPath bezierPathWithCGPath: CGContextCopyPath(context)]; }