如何绘制填充颜色不是实心而是图像的MKCircle

时间:2013-01-28 16:32:42

标签: iphone objective-c mkmapview mkoverlay

我发现了如何围绕地图注释绘制圆圈。 我是这样做的:

     MKCircle *circle = [MKCircle circleWithCenterCoordinate:theCoordinate radius:15000];
     [myMap addOverlay:circle];

 -(MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay
 {
    MKCircleView *circleView = [[MKCircleView alloc] initWithOverlay:overlay];
    circleView.fillColor =[UIColor redColor];

   return circleView;
}

它工作正常,但我想绘制一个圆圈,其填充颜色不是这样的实体:

enter image description here

6 个答案:

答案 0 :(得分:10)

使用MKCircleRenderer答案iOS 7 ...

您应该继承MKCircleRenderer,并覆盖fillPath:inContext方法,类似于此问题的已接受答案。 e.g。

@implementation MKGradientCircleRenderer

- (void)fillPath:(CGPathRef)path inContext:(CGContextRef)context
{

    CGRect rect = CGPathGetBoundingBox(path);

    CGContextAddPath(context, path);
    CGContextClip(context);

    CGFloat gradientLocations[2] = {0.6f, 1.0f};
    // Start color white with 0.25 alpha,
    // End color green with 0.25 alpha
    CGFloat gradientColors[8] = {1.0f, 1.0f, 1.0f, 0.25f, 0.0f, 1.0f, 0.0f, 0.25f};
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColors, gradientLocations, 2);
    CGColorSpaceRelease(colorSpace);

    CGPoint gradientCenter = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
    CGFloat gradientRadius = MIN(rect.size.width, rect.size.height) / 2;

    CGContextDrawRadialGradient(context, gradient, gradientCenter, 0, gradientCenter, gradientRadius, kCGGradientDrawsAfterEndLocation);

    CGGradientRelease(gradient);


}

然后在你的MKMapView委托中,实现以下方法......

-(MKOverlayRenderer *)mapView:(MKMapView*)mapView rendererForOverlay:(id<MKOverlay>)overlay {

    MKCircle * circle = (MKCircle *)overlay;

    MKGradientCircleRenderer * renderer = [[MKGradientCircleRenderer alloc] initWithCircle:circle];

    return renderer;

}

这将允许您实现相同的效果,但使用iOS 7中提供的新方法。

答案 1 :(得分:6)

要使用渐变绘制圆,您必须提供自己的注释视图类,因为现有的都不支持。你可以做的是你可以覆盖- (void)fillPath:(CGPathRef)path inContext:(CGContextRef)context的子类中的方法MKCircleView。以下是一些代码(非优化,带有硬编码填充参数),可帮助您入门:

@interface TWOGradientCircleView : MKCircleView
@end

@implementation TWOGradientCircleView

- (void)fillPath:(CGPathRef)path inContext:(CGContextRef)context
{
    CGRect rect = CGPathGetBoundingBox(path);

    CGContextAddPath(context, path);
    CGContextClip(context);

    CGFloat gradientLocations[2] = {0.6f, 1.0f};
    // Start color white with 0.25 alpha,
    // End color green with 0.25 alpha
    CGFloat gradientColors[8] = {1.0f, 1.0f, 1.0f, 0.25f, 0.0f, 1.0f, 0.0f, 0.25f};
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    CGGradientRef gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColors, gradientLocations, 2);
    CGColorSpaceRelease(colorSpace);

    CGPoint gradientCenter = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
    CGFloat gradientRadius = MIN(rect.size.width, rect.size.height) / 2;

    CGContextDrawRadialGradient(context, gradient, gradientCenter, 0, gradientCenter, gradientRadius, kCGGradientDrawsAfterEndLocation);

    CGGradientRelease(gradient);
}

要使用它,只需将MKCircleView替换为TWOGradientCircleView

- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id)overlay
{
    MKCircleView *circleView = [[TWOGradientCircleView alloc] initWithOverlay:overlay];

    return circleView;
}

如果您想使用图像而不是绘制渐变,可以使用图像绘制替换上面的渐变图。由于放大会使图像模糊,您应该禁用缩放,或者像Apple在WWDC10的会话中演示的那样平铺图像(有关其示例代码的存储库,请参阅here)。使用图案图像设置UIColor对半径为15000不起作用(除非您使用非常非常大的图像;)。

答案 2 :(得分:3)

您是否尝试将填充颜色设置为使用[UIColor colorWithPatternImage:]创建的颜色?

答案 3 :(得分:3)

为了在Swift 2.0(iOS7 +)中实现解决方案,我使用了以下解决方案

import Foundation
import MapKit

class TWOGradientCircleRenderer: MKCircleRenderer {

    override func fillPath(path: CGPath, inContext context: CGContext) {
        let rect:CGRect = CGPathGetBoundingBox(path)

        CGContextAddPath(context, path);
        CGContextClip(context);

        let gradientLocations: [CGFloat]  = [0.6, 1.0];
        let gradientColors: [CGFloat] = [1.0, 1.0, 1.0, 0.25, 0.0, 1.0, 0.0, 0.25];
        let colorSpace = CGColorSpaceCreateDeviceRGB();
        let gradient = CGGradientCreateWithColorComponents(colorSpace, gradientColors, gradientLocations, 2);

        let gradientCenter = CGPointMake(CGRectGetMidX(rect), CGRectGetMidY(rect));
        let gradientRadius = min(rect.size.width, rect.size.height) / 2;

        CGContextDrawRadialGradient(context, gradient, gradientCenter, 0, gradientCenter, gradientRadius, .DrawsAfterEndLocation);
    }
}

在您的MKMapViewDelegate中,您需要添加

func mapView(mapView: MKMapView, rendererForOverlay overlay: MKOverlay) -> MKOverlayRenderer {
        if overlay is MKCircle {
            let circleRenderer = TWOGradientCircleRenderer(overlay: overlay)
            return circleRenderer
        } else {
            return MKOverlayRenderer()
        }
    }

答案 4 :(得分:2)

这个答案适用于Swift 3.0 / iOS 10。

class CircleRenderer: MKCircleRenderer {
    override func fillPath(_ path: CGPath, in context: CGContext) {
        let rect: CGRect = path.boundingBox
        context.addPath(path)
        context.clip()
        let gradientLocations: [CGFloat]  = [0.6, 1.0]
        let gradientColors: [CGFloat] = [1.0, 1.0, 1.0, 0.25, 0.0, 1.0, 0.0, 0.25]
        let colorSpace = CGColorSpaceCreateDeviceRGB()
        guard let gradient = CGGradient(colorSpace: colorSpace, colorComponents: gradientColors, locations: gradientLocations, count: 2) else { return }

        let gradientCenter = CGPoint(x: rect.midX, y: rect.midY)
        let gradientRadius = min(rect.size.width, rect.size.height) / 2
        context.drawRadialGradient(gradient, startCenter: gradientCenter, startRadius: 0, endCenter: gradientCenter, endRadius: gradientRadius, options: .drawsAfterEndLocation)
    }
}

覆盖委托方法:

func mapView(_ mapView: MKMapView, rendererFor overlay: MKOverlay) -> MKOverlayRenderer {
    let circleRenderer = CircleRenderer(overlay: overlay)

    return circleRenderer
}

这方面的一个例子:

enter image description here

答案 5 :(得分:1)

**仅更新答案:

在IOS 7中,fillPath:inContext已弃用为MKCircleView。请尝试使用MKCircleRenderer。

https://developer.apple.com/library/ios/documentation/MapKit/Reference/MKOverlayPathRenderer_class/Reference/Reference.html#//apple_ref/occ/cl/MKOverlayPathRenderer