custom annotation view for maps

I am trying to draw an annotation for map , my view is a subclass of MKAnnotationView

I need a shape something like shown below

What I am getting is like this :

Here is the code which I am using :

- (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();

}

You can achieve the desired effect if you replace your lines with quad curves:

- (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();

}

This employs a quadratic bezier curve, which is a good curve when you don't want inflection points. You can achieve a similar curve with the cubic bezier, but if you're not careful with your control points, you can get undesired inflection points. The quadratic curve is just a little easier with only one control point per curve.

By choosing control points with x values the same as the start and end of the semicircle, it ensures a smooth transition from the circle to the curve leading down to the point. By choosing y values for those control points which are relatively close to the start and end of the semicircle, it ensures that the curve will transition quickly from the semicircle to the point. You can adjust these control points, but hopefully this illustrates the idea.

For illustration of the difference between these two types of curves, see the Curves section of the Paths chapter of the Quartz 2D Programming Guide.

链接地址: http://www.djcxy.com/p/74270.html

上一篇: 当AVCaptureVideoPreviewLayer子视图添加时,UIView忽略大小约束

下一篇: 地图的自定义注释视图