MKAnnotationView with custom view and image view
Asked Answered
X

3

6

In my Map application, instead of showing a pin, I want to show a colored background circle with image in it. The color of the background (which is shade of green in below image) circle is dynamic. It will look as in below image:

enter image description here

I created TCircleView which draws the color in "drawRect"

To show similar annotation, I created object of TCircleView and UIImageView and add them to MKAnnotationView object. Its looking good and visible as expected.

But its not allowing to detect tap/touch to show the call out.

I'm using the below code:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {

    if ([annotation isKindOfClass:[MKPointAnnotation class]]) {
        return nil;
    }

    static NSString *annotationIdentifier = @"StickerPin";

    MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];

    if (!annotationView) {
        annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
        annotationView.canShowCallout = YES;
    }

    TCircleView* circleView = [[TCircleView alloc] init];
    circleView.green = [postObj[@"severity"] floatValue]; //dynamic value coming from server

    UIImageView* imgView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"Piano"]];

    CGRect r = imgView.frame;
    r.size.height = r.size.width = 60;
    imgView.frame = r;
    circleView.frame = r;

    [annotationView addSubview:circleView];
    [annotationView addSubview:imgView];

    return annotationView;
}

Its not allowing to show the callout or not even calling the delegate "didSelectAnnotationView:"
How to show the custom view as annotation on the map?

Xerxes answered 15/2, 2014 at 18:33 Comment(0)
X
3

I created a sub class of annotation view and achieved it. The code is below:

@interface TStickerAnnotationView : MKAnnotationView

@property(nonatomic) float stickerColor;

@end

@interface TStickerAnnotationView () {
    UIImageView *_imageView;
    TCircleView *_circleView;
}


@end

@implementation TStickerAnnotationView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // make sure the x and y of the CGRect are half it's
        // width and height, so the callout shows when user clicks
        // in the middle of the image
        CGRect  viewRect = CGRectMake(-30, -30, 60, 60);

        TCircleView* circleView = [[TCircleView alloc] initWithFrame:viewRect];
        _circleView = circleView;
        [self addSubview:circleView];

        UIImageView* imageView = [[UIImageView alloc] initWithFrame:viewRect];

        // keeps the image dimensions correct
        // so if you have a rectangle image, it will show up as a rectangle,
        // instead of being resized into a square
        imageView.contentMode = UIViewContentModeScaleAspectFit;

        _imageView = imageView;

        [self addSubview:imageView];



    }
    return self;
}

- (void)setImage:(UIImage *)image
{
    // when an image is set for the annotation view,
    // it actually adds the image to the image view
    _imageView.image = image;
}

- (void)stickerColor:(float)color {
    _circleView.green = color;
    [_circleView setNeedsDisplay];
}
Xerxes answered 16/2, 2014 at 15:12 Comment(0)
S
14

The default frame width and height for MKAnnotationView is 0,0.
This is most likely preventing it from responding to touches.

Normally, if you set its image property, the frame is automatically set for you.

Since you're not setting the image and adding subviews instead, try manually setting frame to be at least as big as its largest subview.

For example:

imgView.frame = r;
circleView.frame = r;
annotationView.frame = r;  // <-- add this line
Statutable answered 15/2, 2014 at 18:56 Comment(2)
damn, wish this could have worked. the only insight ive ever seen regarding this @AnnaSheply
This solved the problem for me :-) I had an imageview infront of my annotationView, and it wasn't reacting to taps.. now it works! Thanks AnnaBinal
X
3

I created a sub class of annotation view and achieved it. The code is below:

@interface TStickerAnnotationView : MKAnnotationView

@property(nonatomic) float stickerColor;

@end

@interface TStickerAnnotationView () {
    UIImageView *_imageView;
    TCircleView *_circleView;
}


@end

@implementation TStickerAnnotationView

- (id)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        // make sure the x and y of the CGRect are half it's
        // width and height, so the callout shows when user clicks
        // in the middle of the image
        CGRect  viewRect = CGRectMake(-30, -30, 60, 60);

        TCircleView* circleView = [[TCircleView alloc] initWithFrame:viewRect];
        _circleView = circleView;
        [self addSubview:circleView];

        UIImageView* imageView = [[UIImageView alloc] initWithFrame:viewRect];

        // keeps the image dimensions correct
        // so if you have a rectangle image, it will show up as a rectangle,
        // instead of being resized into a square
        imageView.contentMode = UIViewContentModeScaleAspectFit;

        _imageView = imageView;

        [self addSubview:imageView];



    }
    return self;
}

- (void)setImage:(UIImage *)image
{
    // when an image is set for the annotation view,
    // it actually adds the image to the image view
    _imageView.image = image;
}

- (void)stickerColor:(float)color {
    _circleView.green = color;
    [_circleView setNeedsDisplay];
}
Xerxes answered 16/2, 2014 at 15:12 Comment(0)
S
1

Try looking at this solution- I found it relevant http://blog.jaanussiim.com/2014/01/28/floating-annotations.html

Sheply answered 25/2, 2015 at 18:14 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.