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;
Related
So in my app, I have a mapView that drops pins when the screen is pressed. Once the annotations are dropped, they are placed into an array. There will be multiple pins on the map at one time, and each pin has a identifier property that is an NSNumber. I have another view controller that is pushed onto the stack when the callout button on the annotationView is pressed, and this view has a button that I want to delete the pin from the mapView when pressed. My problem is, I do not know how to pass the identifier of the pin to the second view controller. Here is some code.
This is the method where I drop the pin:
-(void)press:(UILongPressGestureRecognizer *)recognizer
{
CGPoint touchPoint = [recognizer locationInView:_worldView];
CLLocationCoordinate2D touchMapCoordinate = [_worldView convertPoint:touchPoint toCoordinateFromView:_worldView];
geocoder = [[CLGeocoder alloc]init];
CLLocation *location = [[CLLocation alloc]initWithCoordinate:touchMapCoordinate
altitude:CLLocationDistanceMax
horizontalAccuracy:kCLLocationAccuracyBest
verticalAccuracy:kCLLocationAccuracyBest
timestamp:[NSDate date]];
[geocoder reverseGeocodeLocation:location
completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(#"reverseGeocoder:completionHandler: called");
if (error) {
NSLog(#"Geocoder failed with error: %#", error);
} else {
CLPlacemark *place = [placemarks objectAtIndex:0];
geocodedAddress = [NSString stringWithFormat:#"%# %#, %# %#", [place subThoroughfare], [place thoroughfare], [place locality], [place administrativeArea]];
if (UIGestureRecognizerStateBegan == [recognizer state]) {
value = [number intValue];
number = [NSNumber numberWithInt:value + 1];
addressPin = [[MapPoint alloc]initWithAddress:geocodedAddress coordinate:touchMapCoordinate
title:geocodedAddress identifier:number];
NSLog(#"The identifier is %#", number);
[_annotationArray addObject:addressPin];
[_worldView addAnnotation:addressPin];
NSLog(#"The number of pins in the annotation array is: %u",_annotationArray.count);
}
}
}];
}
This is where I create the second view controller:
-(void)mapView:(MKMapView *)mapView
annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
PinViewController *pinViewController = [[PinViewController alloc]init];
[[self navigationController]pushViewController:pinViewController animated:YES];
pinViewController.label.text = view.annotation.title;
}
Here is my MKAnnotation class:
#import <CoreLocation/CoreLocation.h>
#import <MapKit/MapKit.h>
#interface MapPoint : NSObject <MKAnnotation>
{
NSString *_address;
CLLocationCoordinate2D _coordinate;
NSNumber *_identifier;
}
- (id)initWithAddress:(NSString*)address
coordinate:(CLLocationCoordinate2D)coordinate
title:(NSString *)t
identifier:(NSNumber *)ident;
//This is a required property from MKAnnotation
#property (nonatomic, readonly) 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 (copy, nonatomic) NSNumber *identifier;
#end
#import "MapPoint.h"
#implementation MapPoint
#synthesize title, subtitle, animatesDrop, canShowCallout;
#synthesize address = _address, coordinate = _coordinate, identifier = _identifier;
-(id)initWithAddress:(NSString *)address
coordinate:(CLLocationCoordinate2D)coordinate
title:(NSString *)t
identifier:(NSNumber *)ident
{
self = [super init];
if (self) {
_address = [address copy];
_coordinate = coordinate;
_identifier = ident;
[self setTitle:t];
NSDate *theDate = [NSDate date];
subtitle = [NSDateFormatter localizedStringFromDate:theDate
dateStyle:NSDateFormatterMediumStyle
timeStyle:NSDateFormatterMediumStyle];
}
return self;
}
#end
Try following:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
MyAnnotation *myAnnotation = view.annotation;
}
Just add it as a property in your SecondViewController:
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
PinViewController *pinViewController = [[PinViewController alloc]init];
[[self navigationController]pushViewController:pinViewController animated:YES];
pinViewController.label.text = view.annotation.title;
pinViewController.annotation_id = view.annotation.some_id;
}
Add segue from your first ViewController Try to second ViewController and do check your class like following:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control {
[self performSegueWithIdentifier: #"segue_name" sender: view];
}
- (void)prepareForSegue:(UIStoryboardSegue *)segue sender:(id)sender {
if([segue.identifier isEqualToString: #"segue_name"]) {
SecondViewController *vc = segue.destinationViewController;
vc.variable_name = view.annotation.title;
MyAnnotation vc.annotation_id*myAnnotation = view.annotation.some_id;
}annotation;
}
I have a mapView where users press to drop a pin. There may be multiple pins at one time, and each annotation view has a callout that pushes a new view to the stack when it is pressed. What I want to do is pass the title of the annotation view to the label in the second view.
Here is the code where I drop the pin:
-(void)press:(UILongPressGestureRecognizer *)recognizer
{
CGPoint touchPoint = [recognizer locationInView:worldView];
CLLocationCoordinate2D touchMapCoordinate = [worldView convertPoint:touchPoint toCoordinateFromView:worldView];
geocoder = [[CLGeocoder alloc]init];
CLLocation *location = [[CLLocation alloc]initWithCoordinate:touchMapCoordinate
altitude:CLLocationDistanceMax
horizontalAccuracy:kCLLocationAccuracyBest
verticalAccuracy:kCLLocationAccuracyBest
timestamp:[NSDate date]];
[geocoder reverseGeocodeLocation:location
completionHandler:^(NSArray *placemarks, NSError *error) {
NSLog(#"reverseGeocoder:completionHandler: called");
if (error) {
NSLog(#"Geocoder failed with error: %#", error);
} else {
CLPlacemark *place = [placemarks objectAtIndex:0];
address = [NSString stringWithFormat:#"%# %#, %# %#", [place subThoroughfare], [place thoroughfare], [place locality], [place administrativeArea]];
if (UIGestureRecognizerStateBegan == [recognizer state]) {
addressPin = [[MapPoint alloc]initWithCoordinate:touchMapCoordinate
title:address];
[worldView addAnnotation:addressPin];
}
}
}];
}
And here is the code where I call the second view:
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
PinViewController *pinViewController = [[PinViewController alloc]init];
[self passValues];
[[self navigationController]pushViewController:pinViewController animated:YES];
}
You can override MKAnnotation (for example MyLocation)and declare in MyLocation.h file
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface MyLocation : NSObject <MKAnnotation> {
NSNumber *identyfier;
NSString *_name;
NSString *_address;
CLLocationCoordinate2D _coordinate;
}
#property (copy) NSString *name;
#property (copy) NSString *address;
#property (copy) NSNumber *identyfier;
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (id)initWithName:(NSString*)name address:(NSString*)address
coordinate:(CLLocationCoordinate2D)coordinate identyfier:(NSNumber *) identyfier;
#end
in MyLocation.m file:
#import "MyLocation.h"
#implementation MyLocation
#synthesize name = _name;
#synthesize address = _address;
#synthesize coordinate = _coordinate;
#synthesize identyfier = _identyfier;
- (id)initWithName:(NSString*)name address:(NSString*)address
coordinate:(CLLocationCoordinate2D)coordinate identyfier:(NSNumber *)identyfier {
if ((self = [super init])) {
_name = [name copy];
_address = [address copy];
_coordinate = coordinate;
_identyfier = identyfier;
}
return self;
}
In your map view when you declare annotation use this methos:
MyLocation *pin = [[MyLocation alloc] initWithName:place.name address:place.address coordinate:coordinate2D identyfier:some_id];
So for example in your map delegate:
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
you can use:
((MyLocation *)annotation).identyfier
to check selected annotation (of course you can use different variables in MyLocation class)
Usually when i need to pass variables i just create a global variable that then can be read by both view.
There is the
extern (NSString *)some_variable_name, which you put in the .h file and in the .m file you globally put (NSString *)some_variable_name ;
Which the can be read by all views
Or the + sign in front of you variable, which then can be read by all views that includes the view (setting the global at the top in the .m file, and in the .h file by the comman
something = [someview that_variable] ;
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.
I've been stuck on this EXC_BAD_ACCESS error 2 days now. I have a reloadAnnotations method that removes all annotations before adding new annotations. Before removing the annotation this method should be checking to see if the new set contains the same location so it's not removed and re-added. But as soon as I try to trace out the current annotation title I get this error Thread 1: Program received signal: "EXC_BAD_ACCESS"
And when I view the annotation in the debugger the title property says "Invalid Summary". It must be caused by a value not being retained but I've tried everything and can't figure it out.
Why can't I log the annotation title to NSLog?
And why can't I compare each title and coords to other objects?
BrowseController.m
-(void)reloadAnnotations
{
NSMutableArray *toRemove = [NSMutableArray arrayWithCapacity:10];
for (id annotation in _mapView.annotations) {
if (annotation != _mapView.userLocation) {
//ParkAnnotation *pa = (ParkAnnotation *)annotation;
ParkAnnotation *pa = annotation;
NSLog(#"pa.title %#", pa.title); // Thread 1: Program received signal: "EXC_BAD_ACCESS"
[toRemove addObject:annotation];
}
}
// DON'T REMOVE IT IF IT'S ALREADY ON THE MAP!!!!!!
for(RKLocation *loc in locations)
{
CLLocationCoordinate2D location;
location.latitude = (double)[loc.lat doubleValue];
location.longitude = (double)[loc.lng doubleValue];
ParkAnnotation *parkAnnotation = [[ParkAnnotation alloc] initWithTitle:loc.name andCoordinate:location];
[_mapView addAnnotation:parkAnnotation];
}
[_mapView removeAnnotations:toRemove];
}
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
NSLog(#"BrowseViewController map viewForAnnotation");
MKPinAnnotationView *pin = (MKPinAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier: #"anIdentifier"];
if (pin == nil){
pin = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier: #"anIdentifier"] autorelease];
pin.pinColor = MKPinAnnotationColorRed;
pin.animatesDrop = YES;
pin.canShowCallout = YES;
}
else{
pin.annotation = annotation;
}
return pin;
}
ParkAnnotation.h
#import <Foundation/Foundation.h>
#import <MapKit/MapKit.h>
#interface ParkAnnotation : NSObject <MKAnnotation> {
NSString *title;
CLLocationCoordinate2D coordinate;
}
#property (nonatomic, copy) NSString *title;
#property (nonatomic, readonly) CLLocationCoordinate2D coordinate;
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d;
#end
ParkAnnotation.m (edited: see Wolfgangs comments below )
#import "ParkAnnotation.h"
#implementation ParkAnnotation
#synthesize title, coordinate;
- (id)initWithTitle:(NSString *)ttl andCoordinate:(CLLocationCoordinate2D)c2d {
self = [super init];
if (self) {
title = ttl;
coordinate = c2d;
}
return self;
}
- (void)dealloc {
[title release];
[super dealloc];
}
#end
Although you have declared title has a copy type property, it never is copied as you don't use the setter method and directly assigned. You are even releasing it without ownership. Change it like this,
title = [ttl copy];
The initializer in ParkAnnotation.m isn't written following ObjC conventions. The self variable is never set, the designated initializer of a class should follow the following pattern:
- (id)init
{
self = [super init];
if (self)
{
/* custom initialization here ... */
}
return self;
}
Since self is not set, the accessor methods used in the caller will fail; the container object (inside ParkAnnotation.m referenced with self) will be nil or some bogus value when trying to access a property inside the object from another class.
I currently have an XML model getting processed my an NSXMLParser; I get about 340 objects in my model after processing. I place all of the objects on my MKMapView. Once a user "selects" an object (MKAnnotationViewPin); once I start off, the title is populated, coords too (duh?) but the subtitle is set to a place-holder. I process another XML file to retrieve extra information, the subtitle gets updated and populated.
Once the XML file gets parsed I get notified and update its <MKAnnotation> object to reflect the changed subtitle. To reflect the change on the map I have to "unselect" the pin and click it again for it to show the change.
Here is my <MKAnnotation> object:
Header:
#interface CPCustomMapPin : NSObject <MKAnnotation>
{
NSString *_title;
NSString *_annotation;
CLLocationCoordinate2D _coords;
NSString *stationID;
}
#property (nonatomic, retain) NSString *_title;
#property (nonatomic, retain) NSString *_annotation;
#property (nonatomic) CLLocationCoordinate2D _coords;
#property (nonatomic, retain) NSString *stationID;
- (id) initWithTitle: (NSString *) _title withAnnotation: (NSString *) _annotation withCoords: (CLLocationCoordinate2D) _coords withStationID: (NSString *) _id;
Implementation:
#implementation CPCustomMapPin
#synthesize _title, _annotation, _coords, stationID;
- (id) initWithTitle: (NSString *) __title withAnnotation: (NSString *) __annotation withCoords: (CLLocationCoordinate2D) __coords withStationID: (NSString *) _id
{
_title = [[NSString alloc] init];
_annotation = [[NSString alloc] init];
stationID = [[NSString alloc] init];
[self set_title: __title];
[self set_annotation: __annotation];
[self set_coords: __coords];
[self setStationID: _id];
return self;
}
- (NSString *) title
{
return _title;
}
- (NSString *) subtitle
{
return _annotation;
}
- (CLLocationCoordinate2D) coordinate
{
return _coords;
}
- (NSString *) description
{
return [NSString stringWithFormat: #"title: %# subtitle: %# id: %#", _title, _annotation, stationID];
}
- (void) dealloc
{
[_title release];
[_annotation release];
[stationID release];
[super dealloc];
}
#end
Thank you for your valuable input.
Apparently no one knows… I just found this technique:
- (void) closeAnnotation: (id <MKAnnotation>) annotation inMapView: (MKMapView *) mapView
{
[mapView deselectAnnotation: annotation animated: NO];
[mapView selectAnnotation: annotation animated: YES];
}
And of course you call your method accordingly:
Example:
- (void) myMethod
{
for (id <MKAnnotation> _annotation in mapView.annotations)
{
[self closeAnnotation: _annotation inMapView: mapView];
}
}