objective-cannotationscallouts

MapView with multiple annotations with callouts, how to pass title to next view


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

Solution

  • 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)