0

I am parsing some data with some points of interests and trying to show them on map using the MapKit framework. I created a custom class for my objects on the map which i call MyLocation.

MyLocation.h:

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface MyLocation : NSObject <MKAnnotation> {
    NSString *_name;
    NSString *_address;
    NSInteger _eventId;
    CLLocationCoordinate2D _coordinate;
    NSString *title;
    NSString *subtitle;

}

@property (nonatomic , copy) NSString *name;
@property (nonatomic , copy) NSString *address;
@property (nonatomic, assign) NSInteger eventId;
@property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
@property (nonatomic, copy) NSString *title;
@property (nonatomic, copy) NSString *subtitle;

- (id)initWithName:(NSString*)name address:(NSString*)address coordinate:(CLLocationCoordinate2D)coordinate;

@end

MyLocation.m:

#import "MyLocation.h"

@implementation MyLocation
@synthesize name = _name;
@synthesize eventId=_eventId;
@synthesize address = _address;
@synthesize coordinate = _coordinate;
@synthesize title;
@synthesize subtitle;



- (id)initWithName:(NSString*)name address:(NSString*)address coordinate:(CLLocationCoordinate2D)coordinate {
    if ((self = [super init])) {
        _name= [name copy];
        _address = [address copy];
        _coordinate = coordinate;
    }
    return self;
}

- (NSString *)title {
    if ([_name isKindOfClass:[NSNull class]]) {
        NSLog(@"11111111");
        return @"Unknown charge";
    }
    else{
        NSLog(@"222222");
        return _name;

    }
}

- (NSString *)subtitle {
    NSLog(@"HAHAHAHAA");
    return _address;
}

@end

Then on my viewController i do this :

//showing on map the points of interests that are stored on "eventList"
int i=0;
for (parsedItem *event in self.eventsList) {
    CLLocationCoordinate2D coordinate;
    coordinate.latitude = event.latitude;
    coordinate.longitude = event.longitude;
    if(i==0){
        //numbers show map zoom. 500,500 = map stretches 500 meters to the North and the South of current location
        MKCoordinateRegion region =
        MKCoordinateRegionMakeWithDistance (coordinate,1000,1000);
        [mapView setRegion:region animated:NO];
    }
    MyLocation *eventAnnotation = [[MyLocation alloc] initWithName:event.typeEvent address:event.titleEvent coordinate:coordinate] ;        
    eventAnnotation.name = event.typeEvent;
    eventAnnotation.address = event.titleEvent;
    eventAnnotation.eventId = i;
    i++;        
    [mapView addAnnotation:eventAnnotation];
} 

Later i use some more code to give images to the annotations and everything appears on the map BUT if i click on the annotations i dont see the window with the title and the subtitle. I only see the annotations but without the extra information that i should get when i click on them.

I guess theres something wrong with this line of code :

MyLocation *eventAnnotation = [[MyLocation alloc] initWithName:event.typeEvent address:event.titleEvent coordinate:coordinate] ;

Any ideas?

EDIT

just to add that i also use this function:

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

    static NSString *identifier = @"MyLocation";   
    if ([annotation isKindOfClass:[MyLocation class]]) {
        NSLog(@"I got into the class!!!");
        MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
        if (annotationView == nil) {
            annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
        } else {
            annotationView.annotation = annotation;
        }

        annotationView.enabled = YES;
        annotationView.canShowCallout = YES;
        MyLocation *eventAnnotation=annotation;


        if ([eventAnnotation.address isEqualToString: @"Culture_07/02/2012"]) {
            NSLog(@"Mphkeeee");
            annotationView.image=[UIImage imageNamed:@"culture.png"];
            //annotation.title = @"Holla!";
        } else if ([eventAnnotation.address isEqualToString: @"Sports_06/29/2012"]) {
            annotationView.image=[UIImage imageNamed:@"sports.png"];
        } else if ([eventAnnotation.address isEqualToString: @"Accident_06/29/2012"]) {
            annotationView.image=[UIImage imageNamed:@"accident.png"];
        } else if ([eventAnnotation.address isEqualToString: @"Problem_06/29/2012"]) {
            annotationView.image=[UIImage imageNamed:@"problem.png"];
        } else if ([eventAnnotation.address isEqualToString: @"Traffic_07/02/2012"]) {
            annotationView.image=[UIImage imageNamed:@"traffic.png"];
        } else if ([eventAnnotation.address isEqualToString: @"Music_06/29/2012"]) {
            annotationView.image=[UIImage imageNamed:@"music.png"];
        } 

        return annotationView;

    }

    return nil;    
}
  • What class is MyLocation subclass of? i don't see where you set the subtitle property of the annotation as well – Eren Beşel Jul 03 '12 at 12:14
  • @interface MyLocation : NSObject , the last line of code doesnt set the title , subtitle and coordinates?? –  Jul 03 '12 at 12:20
  • it sets the custom properties coordinate, address and name. it doesn't set the subtitle of MKAnnotationView. – Eren Beşel Jul 03 '12 at 12:26
  • But i took this code from another project (from a friend developer) and to his project works. Maybe he does smth else in his code that i am missing but i would swear thats the only think he does with the map.. Do you have any idea how i could add a title and a subtitle? Its not only the subtitle! when i press on the icon nothing happens! Shouldnt be a pop-up window even with blank information?? –  Jul 03 '12 at 12:30
  • Try nslogging eventAnnotation.subtitle and write here the log. – Eren Beşel Jul 03 '12 at 12:41
  • plz also look to my edited answer , thats the last part of code i am using , maybe i am missing smth there –  Jul 03 '12 at 12:41
  • I just nslogged the eventAnnotation.subtitle and it returns the address! So the subtitle is passed correctly.. Why doesnt it work? –  Jul 03 '12 at 12:53
  • In MyLocation.m, in the getter method for title, comment out all the code in the method and put this instead: `return @"hello";`. Run that and see if the callout appears. –  Jul 03 '12 at 14:08
  • OMG... it worked... i just changed the title and left the subtitle as it was and it worked.. and i just realized why it didnt work.. the xml file that i was parsing had an error in the server and returned me an empty title so it was like i had no title... –  Jul 03 '12 at 14:19

3 Answers3

1

Using a custom getter method for the title and subtitle instead of setting those properties explicitly is fine with the map view.

The reason your callouts are not showing is because title (which is returning _name -- which is set to event.typeEvent) is returning a nil or empty string.

Your getter method is checking if _name is of type NSNull but it could be an NSString and still be nil or an empty string.

When title is nil or an empty string, the annotation will not display the callout (even if canShowCallout is set to YES and even if subtitle is returning a non-empty value).

So it's most likely that typeEvent is nil or an empty string.

  • u are completely right. i found that out when a guy in a comment above suggested to nslog the "title" value and actually saw it was nill. Very smart observation though , thank you very much for answering. –  Jul 03 '12 at 19:02
0

Looking at your code, you never actually set the title or subtitle attributes. In the place where you set up your title, do something like this:

eventAnnotation.title = event.typeEvent;
eventAnnotation.subtitle = event.titleEvent;

and make sure you have the title and subtitle properties set up in the .h file.

Edit: Here's the header for one of my annotations:

#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>

@interface MapmarkAnnotation : NSObject
<MKAnnotation>
{
    NSString *title;
    CLLocationCoordinate2D coordinate;
}

@property (nonatomic, copy) NSString *title;
@property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;

@end
nevan king
  • 112,709
  • 45
  • 203
  • 241
  • Shouldnt they be passed with this line of code : MyLocation *eventAnnotation = [[MyLocation alloc] initWithName:event.typeEvent address:event.titleEvent coordinate:coordinate] ; Cause when i try to nslog eventAnnotation.subtitle and eventAnnotation.title i get back the subtitle and the title! Also what do you mean to set the title and subtitle on the .h file? You can see on the .m file the 2 functions... At the .h file is just the header for these functons.. –  Jul 03 '12 at 13:19
  • If it try to do this : eventAnnotation.title = event.typeEvent; i get this error: assigning to property with "readonly" attribute not allowed! –  Jul 03 '12 at 13:23
  • Have you tried setting an `NSLog` inside the `title` method to see if it's ever called? – nevan king Jul 03 '12 at 13:23
  • It's readonly because you probably haven't set up the property, and it has no setter defined. – nevan king Jul 03 '12 at 13:25
  • i just did on both title , subtitle methods and they r both called –  Jul 03 '12 at 13:27
  • You can define a setter by using a @property. – nevan king Jul 03 '12 at 13:31
  • OK, you need to set up @properties for `title` and `subtitle` in the `.h` file. Copy the ones in my answer, add `@synthesize` in the `.m` and you should be good. – nevan king Jul 03 '12 at 13:38
  • I just did , it doesnt work :( look my editted question to see the changes i made on the mylocation.h/m files , in case i did smth wrong –  Jul 03 '12 at 13:48
0

Please refer to the Apple doc. you need to set title and subtitle of an annotation object yourself. not some other property like _address instead. There is also 2 sample projects in that doc, check them out as well.

Eren Beşel
  • 1,047
  • 8
  • 16
  • i just checked the sample codes. In the title , subtitle functions they return a string. smth like return @"mpla mpla"; i return a variable called _address. Whats the problem with that? i dont understand... –  Jul 03 '12 at 14:10