Вопрос по objective-c, cagradientlayer, ios, calayer – Рисовать CAGradient в MKPolyLineView

4

у меня только проблема с моим MKPolyLineView. Я просто пытаюсь сделать цветовой градиент полилинии, но с CAGradient это работает. Я подклассы MKPolylineView и перерисовка в

- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)context

 UIColor *darker = [UIColor blackColor];
    CGFloat baseWidth = self.lineWidth / zoomScale;

    // draw the dark colour thicker
    CGContextAddPath(context, self.path);
    CGContextSetStrokeColorWithColor(context, darker.CGColor);
    CGContextSetLineWidth(context, baseWidth * 1.5);
    CGContextSetLineCap(context, self.lineCap);
    CGContextStrokePath(context);

    // now draw the stroke color with the regular width
    CGContextAddPath(context, self.path);
    CGContextSetStrokeColorWithColor(context, self.strokeColor.CGColor);
    CGContextSetLineWidth(context, baseWidth);
    CGContextSetLineCap(context, self.lineCap);
    CGContextStrokePath(context);

    [super drawMapRect:mapRect zoomScale:zoomScale inContext:context];
}

но даже это не работает (StrokeColor = красный). Любые идеи, как получить градиент в полилинии? (Highcolor, centercolor, lowcolor)

Спасибо всем.

Не могли бы вы опубликовать полный источник этой (или упрощенной версии) проекта? Arek Holko

Ваш Ответ

1   ответ
6

MKPolyline с градиентом, вы можете использовать пользовательский подклассMKPolylineView, Поскольку CoreGraphics не поддерживает обводку пути градиентом, мы должны

преобразовать путь в форму, которая отслеживает край пути, используяCGPathCreateCopyByStrokingPathклип контекст к этой формезаполнить используяCGContextDrawLinearGradient

Вот подкласс, чтобы вы начали:

@interface TWOGradientPolylineView : MKPolylineView

@end

@implementation TWOGradientPolylineView

- (void)strokePath:(CGPathRef)path inContext:(CGContextRef)context
{
    CGFloat lineWidth = CGContextConvertSizeToUserSpace(context, (CGSize){self.lineWidth, self.lineWidth}).width;
    CGPathRef pathToFill = CGPathCreateCopyByStrokingPath(path, NULL, lineWidth, self.lineCap, self.lineJoin, self.miterLimit);
    CGRect rect = CGPathGetBoundingBox(pathToFill);
    CGContextAddPath(context, pathToFill);
    CGPathRelease(pathToFill);
    CGContextClip(context);

    CGFloat gradientLocations[2] = {0.0f, 1.0f};
    CGFloat gradientColors[8] = {1.0f, 0.0f, 0.0f, 0.75f, 1.0f, 1.0f, 0.0f, 0.75f};
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColors, gradientLocations, 2);
    CGColorSpaceRelease(colorSpace);

    CGPoint gradientStart = rect.origin;
    CGPoint gradientEnd = {CGRectGetMaxX(rect), CGRectGetMaxY(rect)};

    CGContextDrawLinearGradient(context, gradient, gradientStart, gradientEnd, kCGGradientDrawsAfterEndLocation);
    CGGradientRelease(gradient);
}

@end

Вот скриншот пути, нарисованного классом выше:

Привет @ r3dsm0k3, я обновил свой ответ с помощью подкласса, который рисует градиент внутри.MKPolyline Tammo Freese
Спасибо за ответ @Tammo, но в iOS7 предпочтительным способом является MKPolylineRenderer. Ajith
Я знаю. Оригинальный вопрос был задан дляMKPolylineViewтак что я ответил за этот класс. Это должно хорошо работать в iOS 7. Чтобы использовать вместо этого подкласс рендерера, код необходимо переместить в-drawMapRect:zoomScale:inContext:и требуется дополнительная работа, чтобы получитьCGPath для .MKPolyline Tammo Freese
это может быть способ, которым приложение Nike Run (cl.ly/RwS1) Делать это? Ajith
Спасибо за публикацию изображения, теперь я понимаю проблему, которую вы хотели бы решить. Чтобы заполнить контур градиентом, его необходимо преобразовать в форму, которую можно заполнить. Это может быть сделаноCGPathCreateCopyByStrokingPath, Я'Я доберусь домой через пару часов и обновлю свой ответ. Tammo Freese

Похожие вопросы