地图的自定义注释视图

时间:2014-05-17 04:28:20

标签: ios core-graphics quartz-graphics quartz-2d quartz-core

我正在尝试为地图绘制注释,我的视图是MKAnnotationView的子类

我需要一个如下所示的形状 enter image description here

我得到的是这样的:

enter image description here

以下是我正在使用的代码:

- (void)drawRect:(CGRect)rect
{
    CGContextRef ctx= UIGraphicsGetCurrentContext();
    UIGraphicsPushContext(ctx);

    CGRect bounds = [self bounds];

    CGPoint topLeft = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGPoint topRight = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));
    CGPoint midBottom = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));

    CGFloat height = bounds.size.height;
    CGFloat width = bounds.size.width;

    //draw semi circle
    CGContextBeginPath(ctx);
    CGContextAddArc(ctx, width/2, height/2, width/2, 0 ,M_PI, YES);

    //draw bottom cone
    CGContextAddLineToPoint(ctx, midBottom.x, midBottom.y);
    CGContextAddLineToPoint(ctx, topRight.x, topRight.y + height/2);  // mid right
    CGContextClosePath(ctx);

    CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
    CGContextFillPath(ctx);

    UIGraphicsPopContext();

}

1 个答案:

答案 0 :(得分:1)

如果用四条曲线替换线条,可以达到预期的效果:

- (void)drawRect:(CGRect)rect
{
    CGContextRef ctx= UIGraphicsGetCurrentContext();
    UIGraphicsPushContext(ctx);

    CGRect bounds = [self bounds];

    CGPoint topLeft = CGPointMake(CGRectGetMinX(rect), CGRectGetMinY(rect));
    CGPoint topRight = CGPointMake(CGRectGetMaxX(rect), CGRectGetMinY(rect));
    CGPoint midBottom = CGPointMake(CGRectGetMidX(rect), CGRectGetMaxY(rect));

    CGFloat height = bounds.size.height;
    CGFloat width = bounds.size.width;

    //draw semi circle
    CGContextBeginPath(ctx);
    CGContextAddArc(ctx, width/2, height/2, width/2, 0 ,M_PI, YES);

    //draw bottom cone
    CGContextAddQuadCurveToPoint(ctx, topLeft.x, height * 2 / 3, midBottom.x, midBottom.y);
    CGContextAddQuadCurveToPoint(ctx, topRight.x, height * 2 / 3, topRight.x, topRight.y + height/2);
    // CGContextAddLineToPoint(ctx, midBottom.x, midBottom.y);
    // CGContextAddLineToPoint(ctx, topRight.x, topRight.y + height/2);  // mid right
    CGContextClosePath(ctx);

    CGContextSetFillColorWithColor(ctx, [UIColor redColor].CGColor);
    CGContextFillPath(ctx);

    UIGraphicsPopContext();

}

这采用二次贝塞尔曲线,当您不想要拐点时,这是一条很好的曲线。您可以使用三次贝塞尔曲线获得类似的曲线,但如果您不小心控制点,则可能会出现不希望的拐点。只需每个曲线一个控制点,二次曲线就更容易了。

通过选择x值与半圆开始和结束相同的控制点,可确保从圆到平滑过渡到该点的平滑过渡。通过为那些相对接近半圆的起点和终点的控制点选择y值,可以确保曲线从半圆快速转换到点。你可以调整这些控制点,但希望这说明了这个想法。

为了说明这两种曲线之间的区别,请参阅 Quartz 2D编程指南的路径章节的Curves部分。

example