Annotations dont show title/subtitle on MapKit , iOS - objective-c

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;
}

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.

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

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.

Related

Custom annotation with custom variable

I currently have a map view controller in which i add annotations to based on some parsed json data.
I'm trying to pass a value from this json data to the following segue and they way i want to do this is to add a custom variable to each annotation (venueId) so when it is pressed i can set a global value that the next segue gets via some logic.
However everything i have tried has resulted in a NUll value for the venueId, my code is as follows:
MyLocation.H
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface MyLocation : NSObject <MKAnnotation>{
NSNumber *venueId;
}
#property (nonatomic,readonly) NSNumber *venueId;
- (id)initWithName:(NSString *)name address:(NSString *)address coordinate:(CLLocationCoordinate2D)coordinate venueId:(NSNumber*)venueId;
#end
MyLocation.M
#import "MyLocation.h"
#import "GlobalData.h"
#interface MyLocation ()
#property (nonatomic,copy) NSString *name;
#property (nonatomic,copy) NSString *address;
#property (nonatomic,assign) CLLocationCoordinate2D coordinate;
#end
#implementation MyLocation
#synthesize venueId = _venueId;
- (id) initWithName:(NSString *)name address:(NSString *)address coordinate:(CLLocationCoordinate2D)coordinate venueId:(NSNumber*)venueId{
if ((self = [super init])) {
self.name = name;
self.address = address;
self.coordinate = coordinate;
_venueId = self.venueId;
}
return self;
}
- (NSString *)title{
return _name;
}
- (NSString *)subtitle{
return _address;
}
- (CLLocationCoordinate2D)coordinate{
return _coordinate;
}
- (NSNumber *)venueId{
return _venueId;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control{
NSLog(#"THE CALL OUT has been pressed");
}
#end
PLotting the venues in my MapViewController.M
// plot venues based on data passed in
- (void)plotVenuePositions{
for (id<MKAnnotation> annotation in _mapView.annotations){
// start fresh and remove any annotations in the view
[_mapView removeAnnotation:annotation];
}
for (NSDictionary *row in [[GlobalData sharedGlobalData]venuesArray]){
NSNumber *venueId = [row objectForKey:#"v_id"];
NSString *venueName =[row objectForKey:#"v_name"];
NSNumber *venueLat = [row objectForKey:#"v_lat"];
NSNumber *venueLon = [row objectForKey:#"v_lon"];
NSString *venueTown = [row objectForKey:#"t_name"];
// create co-ord
CLLocationCoordinate2D coordinate;
// set values
coordinate.latitude = venueLat.doubleValue;
coordinate.longitude = venueLon.doubleValue;
// create annotation instance
MyLocation *annotation = [[MyLocation alloc]initWithName:venueName address:venueTown coordinate:coordinate venueId:venueId];
// add annotation
[_mapView addAnnotation:annotation];
NSLog(#"VNEU ID IS %#",venueId);
NSLog(#"ANNOTATION name is %#", annotation.title);
NSLog(#"ANNOTATION subtitle is %#", annotation.subtitle);
NSLog(#"ANNOTATION description is %#", annotation.description);
NSLog(#"ANNOTATION venue ID IS %#", (MyLocation *)annotation.venueId);
}
}
And finally the annotation checks in MapViewController.M
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation{
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[MyLocation class]]) {
MKAnnotationView *annotationView = (MKAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.image = [UIImage imageNamed:#"pin_orange.png"];
// set the cell to have a callout button
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
else{
annotationView.annotation = annotation;
}
return annotationView;
}
return nil;
}
In the initWithName method, this line:
_venueId = self.venueId;
does not set the current location's venue id to the init method's parameter value venueId.
It sets it to the current location's property value for venueId.
Since that property value is backed by _venueId, the line is effectively setting it equal to itself and since it is initially null, it stays null.
The line should be:
_venueId = venueId;
or if you are not using ARC:
_venueId = [venueId retain];
This line will, however, give you a compiler warning that the "local variable hides the instance variable". This is because the method parameter name is the same as the property name.
Although the change will work, to remove the compiler warning, change the name of the method parameter to something other than venueId (eg. iVenueId) and then the changed line would be:
_venueId = iVenueId;

Map coordinates not decoding

In my app, I am trying to save the pins that are on the map so that they are there when the user opens the app after it is terminated. I have conformed my mkAnnotation class to NSCoding, and implemented the two required methods. The annotations are all stored in a NSMutableArray in a singleton class, so I am really just trying to save the array in the singleton class. Everything is being encoded fine, but I do not think they are being decoded. Here is some code:
This is my MKAnnotation class:
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface MapPoint : NSObject <MKAnnotation, NSCoding>
{
}
- (id)initWithAddress:(NSString*)address
coordinate:(CLLocationCoordinate2D)coordinate
title:(NSString *)t;
#property (nonatomic, readwrite) CLLocationCoordinate2D coordinate;
//This is an optional property from MKAnnotataion
#property (nonatomic, copy) NSString *title;
#property (nonatomic, readonly, copy) NSString *subtitle;
#property (nonatomic) BOOL animatesDrop;
#property (nonatomic) BOOL canShowCallout;
#property (copy) NSString *address;
#property (nonatomic, copy) NSString *imageKey;
#property (nonatomic, copy) UIImage *image;
#end
#implementation MapPoint
#synthesize title, subtitle, animatesDrop, canShowCallout, imageKey, image;
#synthesize address = _address, coordinate = _coordinate;
-(id)initWithAddress:(NSString *)address
coordinate:(CLLocationCoordinate2D)coordinate
title:(NSString *)t {
self = [super init];
if (self) {
_address = [address copy];
_coordinate = coordinate;
[self setTitle:t];
NSDate *theDate = [NSDate date];
subtitle = [NSDateFormatter localizedStringFromDate:theDate
dateStyle:NSDateFormatterShortStyle
timeStyle:NSDateFormatterShortStyle];
}
return self;
}
- (void)encodeWithCoder:(NSCoder *)aCoder {
[aCoder encodeObject:_address forKey:#"address"];
NSLog(#"ENCODING coordLatitude %f coordLongitude %f ", _coordinate.latitude, _coordinate.longitude);
[aCoder encodeDouble:_coordinate.longitude forKey:#"coordinate.longitude"];
[aCoder encodeDouble:_coordinate.latitude forKey:#"coordinate.latitude"];
[aCoder encodeObject:title forKey:#"title"];
}
- (id)initWithCoder:(NSCoder *)aDecoder {
self = [super init];
if (self) {
[self setAddress:[aDecoder decodeObjectForKey:#"address"]];
NSLog(#"DECODING coordLatitude %f coordLongitude %f ", _coordinate.latitude, _coordinate.longitude);
_coordinate.longitude = [aDecoder decodeDoubleForKey:#"coordinate.longitude"];
_coordinate.latitude = [aDecoder decodeDoubleForKey:#"coordinate.latitude"];
[self setTitle:[aDecoder decodeObjectForKey:#"title"]];
}
return self;
}
#end
Here is my singleton class:
#import <Foundation/Foundation.h>
#class MapPoint;
#interface Data : NSObject
{
NSMutableArray *_annotations;
}
#property (retain, nonatomic) NSMutableArray *annotations;
+ (Data *)singleton;
- (NSString *)pinArchivePath;
- (BOOL)saveChanges;
#end
#implementation Data
#synthesize annotations = _annotations;
+ (Data *)singleton {
static dispatch_once_t pred;
static Data *shared = nil;
dispatch_once(&pred, ^{
shared = [[Data alloc] init];
shared.annotations = [[NSMutableArray alloc]init];
});
return shared;
}
- (id)init {
self = [super init];
if (self) {
NSString *path = [self pinArchivePath];
_annotations = [NSKeyedUnarchiver unarchiveObjectWithFile:path];
if (!_annotations) {
_annotations = [[NSMutableArray alloc]init];
}
}
return self;
}
- (NSString *)pinArchivePath {
NSArray *cachesDirectories = NSSearchPathForDirectoriesInDomains(NSCachesDirectory, NSUserDomainMask, YES);
NSString *cachesDirectory = [cachesDirectories objectAtIndex:0];
return [cachesDirectory stringByAppendingPathComponent:#"pins.archive"];
}
- (BOOL)saveChanges {
NSString *path = [self pinArchivePath];
return [NSKeyedArchiver archiveRootObject:[Data singleton].annotations
toFile:path];
}
#end
In my viewDidLoad method on the map view controller, I try and place the annotations in the singleton array on the map with this:
for (MapPoint *mp in [Data singleton].annotations) {
[_worldView addAnnotation:mp];
}
The main problem is in the singleton method in these lines:
dispatch_once(&pred, ^{
shared = [[Data alloc] init];
shared.annotations = [[NSMutableArray alloc]init]; //<-- problem line
});
The shared = [[Data alloc] init]; line decodes and initializes the annotations array.
Then the shared.annotations = [[NSMutableArray alloc]init]; line re-creates and re-initializes the annotations array thus discarding the just-decoded annotations so the singleton always returns an empty array.
Remove the shared.annotations = [[NSMutableArray alloc]init]; line.
As already mentioned in the comment, the other minor issue, which causes simply confusion, is the placement of the NSLog where the coordinate is being decoded. The NSLog should be after the decode is done.

checking which map view annotation is tapped on mkmapview

I am having problem in knowing which annotation is tapped on MKMapView.
let me explain my problem, there is a simple view controller on which map view is loaded.
my annotation class "MapViewAnnotation.h" is as follows
#interface MapViewAnnotation : NSObject <MKAnnotation>
{
NSString *title;
CLLocationCoordinate2D coordinate;
NSString *sID;
NSString *zipCode;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, retain) NSString *sID;
#property (nonatomic, retain) NSString *zipCode;
- (id)initWithTitle:(NSString *)titleOfPin andStoreId:(NSString *)storeIdForDetails andCoordinate:(CLLocationCoordinate2D)coordinateOfPin andZipCode:(NSString *)zip;
here is my "MapViewAnnotation.m" file.
#import "MapViewAnnotation.h"
#import <MapKit/MapKit.h>
#implementation MapViewAnnotation
#synthesize title, coordinate,storeId,zipCode;
- (id)initWithTitle:(NSString *)titleOfPin andStoreId:(NSString *)storeIdForDetails andCoordinate:(CLLocationCoordinate2D)coordinateOfPin andZipCode:(NSString *)zip
{
[super init];
title = titleOfPin;
coordinate = coordinateOfPin;
sID = storeIdForDetails;
zipCode = zip;
return self;
}
-(void)dealloc
{
[title release];
[super dealloc];
}
#end
and this is my viewcontroller.m file
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
//I want to access the sID property of that annotation here. PLEASE HELP ME HOW CAN I DO THAT
if (!storeDetailControllerObject) {
storeDetailControllerObject = [[StoreDetailController alloc]init];
}
// storeDetailControllerObject.storeId = [view.annotation storeId];
[self.navigationController pushViewController:storeDetailControllerObject animated:YES];
From the MKMapViewDelegate protocol reference:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view;
If you handle the event in this method you may know which annotation was selected.
You have to set the MKMapView's delegate and to declare that you class implements the MKMapViewDelegate.
This should work:
MapViewAnnotation *mapViewAnnotation = (MapViewAnnotation*)view.annotation;
if( [mapViewAnnotation isKindOfClass:[MapViewAnnotation class]] ){
storeDetailControllerObject.storeId = mapViewAnnotation.storeId;
}

Adding more annotations to UIMapView

I want to add more annotations to my mapview. I'm working with a class Annotation where there is a method addAnnotation. This method is being called in my UIViewController when I want to add a new annotation.
But for some reason, only the annotation I added last, is displayed.
Annotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MKAnnotation.h>
#interface Annotation : NSObject {
CLLocationCoordinate2D cooridnate;
NSString *title;
NSString *subtitle;
}
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
#property (nonatomic, retain) NSMutableArray *locations;
-(void)addAnnotation: (NSString *)initTitle : (NSString *)initSubtitle : (CLLocationCoordinate2D) initCoordinate;
#end
Annotation.m
#import "Annotation.h"
#implementation Annotation
#synthesize coordinate, title, subtitle, locations;
-(void)addAnnotation: (NSString *)initTitle : (NSString *)initSubtitle : (CLLocationCoordinate2D) initCoordinate {
locations = [[NSMutableArray alloc] init];
self.coordinate = initCoordinate;
self.title = [NSString stringWithFormat:#"%#", initTitle];
self.subtitle = [NSString stringWithFormat:#"%#", initSubtitle];
[locations addObject:self]; // add all my anotations with location to an array
}
#end
Method in my UIViewController
#import "MapViewController.h"
#interface MapViewController ()
#end
#implementation MapViewController
#synthesize mapView;
#pragma mark - ViewController methods
- (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil
{
self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];
if (self) {
// Custom initialization
}
return self;
}
- (void)viewDidLoad
{
[super viewDidLoad];
// Do any additional setup after loading the view.
[self initMapView];
ann = [[Annotation alloc] init]; // making place in memory
}
- (void)didReceiveMemoryWarning
{
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
}
#pragma mark - UIMapController methods
- (void)mapViewDidFinishLoadingMap:(MKMapView *)mapView {
[self createAnnotations];
}
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
//If annotation = user position ==> DON'T CHANGE
return nil;
}
MKPinAnnotationView *MyPin=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"current"];
MyPin.pinColor = MKPinAnnotationColorRed;
UIButton *advertButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[advertButton addTarget:self action:#selector(showInfo:) forControlEvents:UIControlEventTouchUpInside];
MyPin.rightCalloutAccessoryView = advertButton;
MyPin.draggable = NO;
MyPin.highlighted = NO;
MyPin.animatesDrop= FALSE;
MyPin.canShowCallout = YES;
return MyPin;
}
#pragma mark - MY Methods
-(void) initMapView {
[mapView setMapType:MKMapTypeStandard]; // standaard maptype
[mapView setScrollEnabled:YES];
[mapView setZoomEnabled:YES];
[mapView setDelegate:self]; // gegevens van de map terugsturen naar deze viewController en de gebruiker
[mapView setShowsUserLocation:YES];
[self focusWorld];
}
-(void) createAnnotations {
[self initSomeExamples];
[self.mapView addAnnotations: ann.locations];
}
-(void) focusWorld {
MKCoordinateRegion worldRegion = MKCoordinateRegionForMapRect(MKMapRectWorld); // regio instellen op World
mapView.region = worldRegion; // regio doorgeven naar onze mapView
}
-(void) initSomeExamples {
// Washington
l1.latitude = 38.892102;
l1.longitude = -77.029953;
// Antwerp
l2.latitude = 51.219787;
l2.longitude = 4.411011;
// Egypt
l3.latitude = 29.993002;
l3.longitude = 31.157227;
// Brazil
l4.latitude = -22.900846;
l4.longitude = -43.212662;
[ann addAnnotation:#"America has a new President !" :#"Washington DC" :l1]; // call method to add an annotation with these parameters
[ann addAnnotation:#"Revolutionary app by Belgium student" :#"Antwerp" :l2];
[ann addAnnotation:#"The new Arabic revolution" :#"Egypt, Tahir square" :l3];
[ann addAnnotation:#"World Championchip football" :#"Rio de Janeiro" :l4];
}
#pragma mark - ACTIONS
-(void)showInfo:(id)sender {
NSLog(#"Show info");
}
#end
You don't need locations #property and - addAnnotation: method. One MKAnnotation object represents a location.
My suggestion is to modify Annotation class accordingly, as well as conforming and create it's objects as many as number of locations you would like to annotate.
Remove locations #property and -addAnnotation: method from Annotation.h/m
Annotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MKAnnotation.h>
#interface Annotation : NSObject <MKAnnotation> {
CLLocationCoordinate2D coordinate;
NSString *title;
NSString *subtitle;
}
#property (nonatomic, assign) CLLocationCoordinate2D coordinate;
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
-(id) initWithTitle: (NSString *)initTitle : (NSString *)initSubtitle : (CLLocationCoordinate2D) initCoordinate;
#end
Annotation.m
#import "Annotation.h"
#implementation Annotation
#synthesize coordinate, title, subtitle;
-(id) initWithTitle: (NSString *)initTitle : (NSString *)initSubtitle : (CLLocationCoordinate2D) initCoordinate {
self = [super init];
if ( self ) {
self.coordinate = initCoordinate;
self.title = [NSString stringWithFormat:#"%#", initTitle];
self.subtitle = [NSString stringWithFormat:#"%#", initSubtitle];
}
return self; // correction appreciated.
}
#end
Some methods changed in your view controller
-(void) initSomeExamples {
// Washington
l1.latitude = 38.892102;
l1.longitude = -77.029953;
// Antwerp
l2.latitude = 51.219787;
l2.longitude = 4.411011;
// Egypt
l3.latitude = 29.993002;
l3.longitude = 31.157227;
// Brazil
l4.latitude = -22.900846;
l4.longitude = -43.212662;
NSArray *annotations = #[
[[Annotation alloc] initWithTitle:#"America has a new President !" :#"Washington DC" :l1],
[[Annotation alloc] initWithTitle:#"Revolutionary app by Belgium student" :#"Antwerp" :l2],
[[Annotation alloc] initWithTitle:#"The new Arabic revolution" :#"Egypt, Tahir square" :l3],
[[Annotation alloc] initWithTitle:#"World Championchip football" :#"Rio de Janeiro" :l4] ];
// Adding 4 annotation objects
[self.mapView addAnnotations:annotations];
}
-(void) createAnnotations {
[self initSomeExamples];
// Annotations are added in -initSomeExamples method.
}

selectAnnotation does not show callout

I want to change the callout shown on the MKMapView. When I call
[self.mapView selectAnnotation:annotation animated:YES];
it pans the map to the annotation, but does not show its callout. How do I get it to show the callout?
Set the title, and optionally the subtitle property on the annotation object. MapKit will automatically show a callout.
#interface MyAnnotation : NSObject <MKAnnotation> {
NSString *title;
NSString *subtitle;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, copy) NSString *subtitle;
#end
And the implementation,
#import "MyAnnotation.h"
#implementation MyAnnotation
#synthesize title, subtitle;
#end
Usage,
MyAnnotation *foo = [[MyAnnotation alloc] init];
foo.title = #"I am Foo";
foo.subtitle = "I am jus' a subtitle";
You should implement the MKAnnotation Delegate method
-(MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
static NSString *AnnotationViewIdentifier = #"AnnotationViewIdentifier";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewIdentifier];
if (annotationView == nil)
{
annotationView = [[[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:AnnotationViewIdentifier]autorelease];
}
annotationView.canShowCallout = YES;
return annotationView;
}