更新时间:2022-12-30 13:01:40
我想出的一个想法就是创建一个CGPath并每次用渐变来抚摸它当 drawMapRect
方法被调用时,因为 MKPolylineView
被 MKPlolylineRenderer $ c $替换c>在ios7中。
One of the idea I came up is to create a CGPath and stroke it with gradient every time when drawMapRect
method been called, since the MKPolylineView
is replaced by MKPlolylineRenderer
in ios7.
我试图通过继承 MKOverlayPathRenderer
来实现这个,但是我没有选择单独的CGPath ,然后我找到一个名为的神秘方法 - (void)strokePath:(CGPathRef)路径inContext:(CGContextRef)context
这听起来像我需要的,但它不会被调用如果你在覆盖 drawMapRect
时没有调用super方法。
I tried to implement this by subclassing a MKOverlayPathRenderer
but I failed to pick out individual CGPath, then I find a mysterious method named-(void) strokePath:(CGPathRef)path inContext:(CGContextRef)context
which sounds like what I need, but it will not be called if you don't call the super method when you override your drawMapRect
.
这就是我现在正在努力的事情。
thats what Im working out for now.
我会继续这样做,如果我找到了什么我会回来并更新答案。
I'll keep trying so if I work out something I'll come back and update the answer.
======的更新强> ================================ ================
=========UPDATE================================================
这就是我最近解决的问题,我几乎实现了上面提到的基本思想但是,我仍然无法根据特定的mapRect选择单独的PATH,所以我只是在所有路径的boundingBox与当前mapRect相交时同时绘制所有具有渐变的路径。糟糕的伎俩,但现在工作。
So that is what I'm worked out these days, I almost implemented the basic idea mentioned above but yes, I still cannot pick out an individual PATH according to specific mapRect, so I just draw all paths with gradient at the same time when the boundingBox of all paths intersects with current mapRect. poor trick, but work for now.
在 - (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext :( CGContextRef)context
render类中的方法,我这样做:
In the -(void) drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
method in render class, I do this:
CGMutablePathRef fullPath = CGPathCreateMutable();
BOOL pathIsEmpty = YES;
//merging all the points as entire path
for (int i=0;i< polyline.pointCount;i++){
CGPoint point = [self pointForMapPoint:polyline.points[i]];
if (pathIsEmpty){
CGPathMoveToPoint(fullPath, nil, point.x, point.y);
pathIsEmpty = NO;
} else {
CGPathAddLineToPoint(fullPath, nil, point.x, point.y);
}
}
//get bounding box out of entire path.
CGRect pointsRect = CGPathGetBoundingBox(fullPath);
CGRect mapRectCG = [self rectForMapRect:mapRect];
//stop any drawing logic, cuz there is no path in current rect.
if (!CGRectIntersectsRect(pointsRect, mapRectCG))return;
然后我逐点拆分整个路径以单独绘制其渐变。
请注意色调
数组,其中包含映射每个位置速度的色调值。
Then I split the entire path point by point to draw its gradient individually.
note that the hues
array containing hue value mapping each velocity of location.
for (int i=0;i< polyline.pointCount;i++){
CGMutablePathRef path = CGPathCreateMutable();
CGPoint point = [self pointForMapPoint:polyline.points[i]];
ccolor = [UIColor colorWithHue:hues[i] saturation:1.0f brightness:1.0f alpha:1.0f];
if (i==0){
CGPathMoveToPoint(path, nil, point.x, point.y);
} else {
CGPoint prevPoint = [self pointForMapPoint:polyline.points[i-1]];
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){self.lineWidth,self.lineWidth}).width;
CGPathRef pathToFill = CGPathCreateCopyByStrokingPath(path, NULL, lineWidth, self.lineCap, self.lineJoin, self.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);
CGGradientRelease(gradient);
CGContextRestoreGState(context);//<--Don't forget to restore your context.
}
pcolor = [UIColor colorWithCGColor:ccolor.CGColor];
}
这是所有核心绘图方法,当然你需要点
, velocity
在你的覆盖类中,用CLLocationManager提供它们。
That is all the core drawing method and of course you need points
, velocity
in your overlay class and feed them with CLLocationManager.
最后一点是如何得到 hue
超出速度的值,嗯,我发现如果0.03~0.3范围内的色调恰好代表从红色到绿色,那么我做一些按比例映射到色调和速度。
the last point is how to get hue
value out of velocity, well, I found that if hue ranging from 0.03~0.3 is exactly represent from red to green, so I do some proportionally mapping to hue and velocity.
最后一个,这里是这个演示的完整来源: https://github.com/wdanxna/GradientPolyline
last of the last, here you are this is full source of this demo:https://github.com/wdanxna/GradientPolyline
如果不能不恐慌看到你画的线,我只是将地图区域放在我的位置上:))
don't panic if can't see the line you draw, I just position the map region on my position :)