Одна из идей, которую я придумал, - создать CGPath и обводить его градиентом каждый раз, когда вызывается метод drawMapRect
, поскольку MKPolylineView
заменяется на MKPlolylineRenderer
в ios7.
Я попытался реализовать это, создав подкласс MKOverlayPathRenderer
, но мне не удалось выбрать отдельный CGPath, затем я нашел таинственный метод с именем -(void) strokePath:(CGPathRef)path inContext:(CGContextRef)context
, который звучит так, как мне нужно, но он не будет вызываться, если вы не вызоветеСупер метод, когда вы переопределяете свой drawMapRect
.
Это то, над чем я сейчас работаю.
Я буду продолжать пытаться, поэтому, если я что-то решу, я вернусь и обновлю ответ.
========= ОБНОВЛЕНИЕ ================================================
Так вот, над чем я работал в эти дни, я почти реализовал основную идею, упомянутую выше, но да, я все еще не могу выбрать отдельный PATH в соответствии с конкретным mapRect, поэтому япросто нарисуйте все пути с градиентом одновременно, когда boundingBox всех путей пересекается с текущим mapRect.плохой трюк, но пока работает.
В методе -(void) drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context
класса рендеринга я делаю это:
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;
Затем я разделяю всю точку пути на точку, чтобы нарисовать ее градиентиндивидуально.обратите внимание, что массив hues
, содержащий значение оттенка, отображающее каждую скорость местоположения.
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];
}
Это все основной метод рисования, и, конечно, вам нужно points
, velocity
в классе оверлея и в фиде.их с помощью CLLocationManager.
последний пункт - как вывести значение hue
из скорости, ну, я обнаружил, что если оттенок в диапазоне от 0,03 ~ 0,3 точно соответствует от красного к зеленому, поэтому я делаю некоторые пропорциональноотображение на оттенок и скорость.
последний из последних, вот вы здесь, это полный источник этой демонстрации: https://github.com/wdanxna/GradientPolyline
не паникуйте, если не видите линии, которую вы рисуетеЯ просто размещаю регион карты на своей позиции:)