我正在寻找一种方法,使用CGContextRef沿着它的路径绘制一条线性渐变线。我已经尝试了几种方法,但大多数都专注于用渐变填充区域(rect),这不是我需要的。
我使用以下代码使用CGPathRef绘制实线。我真正需要的是一个平滑的线性渐变,从第一行的color1开始,到行的最后一点以color2结束。
有谁知道如何实现这个目标?
- (CGMutablePathRef)generatedPath
{
CGMutablePathRef path = CGPathCreateMutable();
CGPathMoveToPoint(path, nil, 20, 10);
CGPathAddLineToPoint(path, nil, 100, 100);
CGPathAddLineToPoint(path, nil, 140, 120);
CGPathAddLineToPoint(path, nil, 160, 100);
CGPathAddLineToPoint(path, nil, 210, 70);
CGPathAddLineToPoint(path, nil, 250, 10);
return path;
}
- (void)drawRect:(CGRect)rect {
[super drawRect:rect];
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGMutablePathRef path = [self generatedPath];
CGContextAddPath(ctx, path);
CGColorRef color = [UIColor redColor].CGColor;
CGContextSetLineWidth(ctx, 8.0);
CGContextSetStrokeColorWithColor(ctx, color);
CGContextStrokePath(ctx);
}
======的更新 ============================== ==================
我实际上发现这个问题与我需要的问题非常相似:Gradient Polyline with MapKit ios
我使用以下代码来实现跟随行的路径的渐变。作为评论,不要介意获取和传递路径点的低效方式。我稍后会对此进行优化:
- (NSArray*)generatePathPoints {
NSMutableArray *points = [[NSMutableArray alloc] init];
[points addObject:[NSValue valueWithCGPoint:CGPointMake(20, 50)]];
[points addObject:[NSValue valueWithCGPoint:CGPointMake(100, 100)]];
[points addObject:[NSValue valueWithCGPoint:CGPointMake(140, 120)]];
[points addObject:[NSValue valueWithCGPoint:CGPointMake(160, 100)]];
[points addObject:[NSValue valueWithCGPoint:CGPointMake(210, 70)]];
[points addObject:[NSValue valueWithCGPoint:CGPointMake(250, 10)]];
return points;
}
- (CGMutablePathRef)pathFromPoints: (NSArray*)points;
{
CGMutablePathRef path = CGPathCreateMutable();
for (int i = 0; i < points.count; i++) {
NSValue *pointValue = points[i];
CGPoint point = [pointValue CGPointValue];
if(i == 0){
CGPathMoveToPoint(path, nil, point.x, point.y);
}
else{
CGPathAddLineToPoint(path, nil, point.x, point.y);
}
}
return path;
}
- (void)drawRect:(CGRect)rect {
CGContextRef context = UIGraphicsGetCurrentContext();
NSArray *points = [self generatePathPoints];
CGFloat widthOfLine = 8.0;
CGLineCap lineCap = kCGLineCapRound;
CGLineJoin lineJoin = kCGLineJoinRound;
int miterLimit = 10;
UIColor *ccolor, *pcolor;
for (int i=0;i< points.count;i++){
CGMutablePathRef path = CGPathCreateMutable();
CGPoint point = ((NSValue*)points[i]).CGPointValue;
ccolor = [self colorForPointAtIndex:i points:points];
if (i==0){
CGPathMoveToPoint(path, nil, point.x, point.y);
} else {
CGPoint prevPoint = ((NSValue*)points[i-1]).CGPointValue;
CGPathMoveToPoint(path, nil, prevPoint.x, prevPoint.y);
CGPathAddLineToPoint(path, nil, point.x, point.y);
CGFloat pc_r,pc_g,pc_b,pc_a,
cc_r,cc_g,cc_b,cc_a;
[pcolor getRed:&pc_r green:&pc_g blue:&pc_b alpha:&pc_a];
[ccolor getRed:&cc_r green:&cc_g blue:&cc_b alpha:&cc_a];
CGFloat gradientColors[8] = {pc_r,pc_g,pc_b,pc_a,
cc_r,cc_g,cc_b,cc_a};
CGFloat gradientLocation[2] = {0,1};
CGContextSaveGState(context);
CGFloat lineWidth = CGContextConvertSizeToUserSpace(context, (CGSize){widthOfLine,widthOfLine}).width;
CGPathRef pathToFill = CGPathCreateCopyByStrokingPath(path, NULL, lineWidth, lineCap, lineJoin, miterLimit);
CGContextAddPath(context, pathToFill);
CGContextClip(context);//<--clip your context after you SAVE it, important!
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColors, gradientLocation, 2);
CGColorSpaceRelease(colorSpace);
CGPoint gradientStart = prevPoint;
CGPoint gradientEnd = point;
CGContextDrawLinearGradient(context, gradient, gradientStart, gradientEnd, kCGGradientDrawsAfterEndLocation | kCGGradientDrawsBeforeStartLocation);
CGGradientRelease(gradient);
CGContextRestoreGState(context);//<--Don't forget to restore your context.
}
pcolor = [UIColor colorWithCGColor:ccolor.CGColor];
}
}
-(UIColor*) colorForPointAtIndex: (NSUInteger)index points:(NSArray*)points {
return [UIColor colorWithRed:1.0 green:0 blue:0 alpha:(1.0 / points.count) * index];
}
这会产生我需要的几乎所有。虽然只有微小的故障: http://imgur.com/gn0JE5z
正如您所看到的那样,行结尾是重叠的,这通常不会成为问题。但由于线条透明,我得到了这种不必要的副作用。
有人知道怎么离开这里吗?