5

i'm working on a custom annotationview that show a image of background, with inside a custom image. I've based my code from this: Custom MKAnnotationView with frame,icon and image And my actually code is:

    else if ([annotation isKindOfClass:[ImagePin class]]){
       static NSString *identifierImage = @"ImagePinLocation";
        MKAnnotationView *annotationImageView = (MKAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:identifierImage];
       if(annotationImageView){
         return annotationImageView;
       }
       else {
            annotationImageView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifierImage];
            annotationImageView.canShowCallout = YES;

            annotationImageView.image = [UIImage imageNamed:@"image_bg_mappa"];

            UIImage *frame = [UIImage imageNamed:@"image_bg_mappa"];
            ImagePin *imagePinImage = annotation;
            NSLog(@"%@", [NSString stringWithFormat:@"%@", imagePinImage.image]);


            NSString *urlStringForImage = [NSString stringWithFormat:@"%@", imagePinImage.image];
            NSURL *urlForImage = [NSURL URLWithString:urlStringForImage];
            UIImageView *imageView = [[UIImageView alloc] init];

            [imageView setImageWithURL:[NSURL URLWithString:[NSString stringWithFormat:@"%@", urlForImage]] placeholderImage:[UIImage imageNamed:@"avatar-placeholder.png"]];

            UIGraphicsBeginImageContext(CGSizeMake(annotationImageView.image.size.width, annotationImageView.image.size.height));

            [frame drawInRect:CGRectMake(0, 0, frame.size.width, frame.size.height)];
            [imageView.image drawInRect:CGRectMake(2, 2, 48, 38)]; // the frame your inner image

            annotationImageView.image = UIGraphicsGetImageFromCurrentImageContext();

            UIGraphicsEndImageContext();

            UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
            [rightButton addTarget:self action:@selector(writeSomething:) forControlEvents:UIControlEventTouchUpInside];
            [rightButton setTitle:@"" forState:UIControlStateNormal];
            annotationImageView.canShowCallout = YES;
            annotationImageView.rightCalloutAccessoryView = rightButton;
            annotationImageView.enabled = YES;
        return annotationImageView;
        }
    }

And then i have two method:

(void)writeSomething {        
}

(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {    
}

But:

  1. Not show my rightButton callout(not show also the button)
  2. I prefer that when i click on the full image/annotation it call mapView annotationView method.

How i can do it ? Why when i click on annotation, it not call my calloutAccessoryControlTapped method ? In this map i have also more different type of pin(mkpinannotation), and works fine(also the method calloutAccessoryControlTapped works fine with these pins). Where is the problem ? Thanks to all, and sorry for my bad english(I'm learning it).

EDIT: My full code for viewForAnnotation method: https://gist.github.com/anonymous/6224519e308d6bf56c4c The MKPinAnnotation works fine.

EDIT: This is my ImagePin.h

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
@interface ImagePin : NSObject <MKAnnotation>

- (id)initWithImage:(NSString*)image imagebeachId:(NSString*)imagebeachId coordinate:(CLLocationCoordinate2D)coordinate;
//- (MKMapItem*)mapItem;
@property (nonatomic, copy) NSString *imagebeachId;
@property (nonatomic, copy) NSString *image;
@property (nonatomic, assign) CLLocationCoordinate2D theCoordinate;
@end

And my ImagePin.m

#import "ImagePin.h"
#import <AddressBook/AddressBook.h>

@interface ImagePin ()

@end

@implementation ImagePin
@synthesize image = _image;
@synthesize imagebeachId = _imagebeachId;
@synthesize theCoordinate = _theCoordinate;

- (id)initWithImage:(NSString*)image imagebeachId:(NSString*)imagebeachId coordinate:(CLLocationCoordinate2D)coordinate {
    if ((self = [super init])) {
        //self.address = address;
        self.image = image;
        self.imagebeachId = imagebeachId;
        self.theCoordinate = coordinate;
    }
    return self;
}
- (NSString *)title {
    return @"";
}
- (NSString *)subtitle {
    return _image;
}

- (CLLocationCoordinate2D)coordinate {
    return _theCoordinate;
}
@end

EDIT: This is where i add annotation:

- (void)imagePositions:(NSDictionary *)responseData {
    for (id<MKAnnotation> annotation in self.mapView.annotations) {
        if ([annotation isKindOfClass:[ImagePin class]]){
            //[self.mapView removeAnnotation:annotation];
        }
    }

    for (NSArray *row in responseData) {
        NSString * imageBeachId = [row valueForKey:@"id"];

        NSNumber * latitude = [row valueForKey:@"lat"];


        NSNumber * longitude = [row valueForKey:@"lng"];
        NSString * imageBeach = [row valueForKey:@"fb_photo_url"];


        CLLocationCoordinate2D coordinate;
        coordinate.latitude = latitude.doubleValue;
        coordinate.longitude = longitude.doubleValue;
        ImagePin *annotation = [[ImagePin alloc] initWithImage:imageBeach imagebeachId:imageBeachId coordinate:coordinate];

        [self.mapView addAnnotation:annotation];
    }
}
Community
  • 1
  • 1
Riccardo Rossi
  • 161
  • 1
  • 9
  • set `userInteractionEnabled = YES;` ? – Elf Sundae Jul 17 '13 at 11:17
  • I tried with annotationImageView.userInteractionEnabled = YES; but not works...when i clicked nothing happens. – Riccardo Rossi Jul 17 '13 at 11:25
  • This is my full code of viewForAnnotation: https://gist.github.com/anonymous/6224519e308d6bf56c4c – Riccardo Rossi Jul 17 '13 at 11:34
  • 1
    You are returning a blank `title` in ImagePin. If an annotation's title is blank, it will not display a callout (even if canShowCallout is YES). –  Jul 17 '13 at 12:59
  • @anna-karenina You have right! there is a way for not have the callout showed and only call the action calloutAccessoryControlTapped ? i don't want show the callout over my custom image pin. – Riccardo Rossi Jul 17 '13 at 14:12
  • @anna-karenina If you can do a answer with your reply for all is better, so i can chooce like "winner" and can return useful to other people! – Riccardo Rossi Jul 17 '13 at 14:13
  • @AnnaKarenina I have fixed all thanks to this : http://stackoverflow.com/questions/7164469/ios-mapkit-custom-callout always you! – Riccardo Rossi Jul 17 '13 at 14:23

3 Answers3

6

I have fixed all! The problem is that title can't be empty(i was using @""... with a @"AAA works fine) and then for not show the callout i have done:

annotationView.canShowCallout = NO;

and implemented:

-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
    //here you action
}

A BIG thanks to Anna(the solution is your)!

Riccardo Rossi
  • 161
  • 1
  • 9
1

First checkout that you give the delegate to MapView or not , if not then give the delegate like bellow..

yourMapView.delegate = self;

Also in .h file define that delegate like bellow..

@interface ViewController : UIViewController<MKMapViewDelegate,MKAnnotation>{...

after check that this bellow method called when accessory tapped...

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    NSLog(@"Do something ");
}

UPDATE:

Instead of Custom Button try to use it...

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

    NSLog(@"viewForAnnotation...");

    static NSString *identifier = @"MyLocation";
    if ([annotation isKindOfClass:[ImagePin class]]) {

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

        if (annotationView == nil)
        {
            annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier] autorelease];
        }

        if (annotation == mapView.userLocation)
            return nil;

        annotationView.image = [UIImage imageNamed:@"yourImageName.png"];
        annotationView.annotation = annotation;
        annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        annotationView.rightCalloutAccessoryView.tag = 101;

        annotationView.canShowCallout = YES;
        //  annotationView.animatesDrop = YES;
        return annotationView;
    }

    return nil;
}
Paras Joshi
  • 20,427
  • 11
  • 57
  • 70
  • The delegate is fine, because i have other type of pin(mkpinannotation), and works fine and call also calloutAccessoryControlTapped. – Riccardo Rossi Jul 17 '13 at 11:31
  • @RiccardoRossi i update now answer use `-(void)writeSomething:(id)sender` instead of you defined.. – Paras Joshi Jul 17 '13 at 11:33
  • Nothing happens also with -(void)writeSomething:(id)sender (and the rightButton isn't showed). – Riccardo Rossi Jul 17 '13 at 11:36
  • @RiccardoRossi check out this http://www.mapbox.com/mapbox-ios-sdk/examples/callout-accessory-view/ – Paras Joshi Jul 17 '13 at 11:42
  • i will checkout your whole code and post comment but see another demo like your requirement from this link https://github.com/ryanmaxwell/GoogleMapsCalloutView/blob/master/GoogleMapsCalloutViewDemo/MyViewController.m :) i hope its helpful to you.... – Paras Joshi Jul 17 '13 at 12:17
  • @RiccardoRossi first check out that Image full name and set that also check out that image url.. here may be it not display because of it not get the image and set to `nil` so first check out that... – Paras Joshi Jul 17 '13 at 12:24
  • The MKAnnotation is showed fine... http://cl.ly/image/0m0M2O0h112R but not the right button or if i tapped on the image(mkannotation), nothing happens...this is my problem :( – Riccardo Rossi Jul 17 '13 at 12:30
  • instead of your code use my code.. comment your `viewForAnnotation:` method and paste my new one above and let me know whats happen... – Paras Joshi Jul 17 '13 at 12:35
  • I tried and i see this annotation: http://cl.ly/image/220C0E0t462h (without inner image, and ok), but if i click nothing happens. – Riccardo Rossi Jul 17 '13 at 12:47
  • can you zoom mapview and scrolled mapview?? – Paras Joshi Jul 17 '13 at 12:52
  • Yes, anyway i edited my main topic, with my .h and .m imagepin files...maybe can be useful! – Riccardo Rossi Jul 17 '13 at 12:53
  • instead of your this custom code use another demo i will post my own code tomorrow just post the comment tomorrow... use this demo https://github.com/ryanmaxwell/GoogleMapsCalloutView/blob/master/GoogleMapsCalloutViewDemo/MyViewController.m or try another – Paras Joshi Jul 17 '13 at 13:09
0

For anyone else that stumbles upon this post while implementing a custom MKAnnotationView, the problem may also be that you have to explicitly set the frame of your view.

MKMapView MKPointAnnotation tap event not called

Community
  • 1
  • 1
mjmayank
  • 194
  • 1
  • 10