3

Currently I can drop pins around the map. Now I want the annotation title to display the address of where the pin is dropped.

I've had a look at this but cant get mine to work:
Set annotation's title as current address

Code in my ViewController.m

Updated.

- (void)addPinToMap:(UIGestureRecognizer *)gestureRecognizer
{
    if (gestureRecognizer.state != UIGestureRecognizerStateBegan)
        return;

    CGPoint touchPoint = [gestureRecognizer locationInView:self.map];
    CLLocationCoordinate2D touchMapCoordinate =
    [self.map convertPoint:touchPoint toCoordinateFromView:self.map];

    CLLocation *currentLocation = [[CLLocation alloc]
                                   initWithLatitude:touchMapCoordinate.latitude
                                   longitude:touchMapCoordinate.longitude];

    [self.geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemark, NSError *error) {

        //initialize the title to "unknown" in case geocode has failed...
        NSString *annTitle = @"Address unknown";

        //set the title if we got any placemarks...
        if (placemark.count > 0)
        {
            CLPlacemark *topResult = [placemark objectAtIndex:0];
            annTitle = [NSString stringWithFormat:@"%@ %@ %@ %@", topResult.country, topResult.locality, topResult.subLocality, topResult.thoroughfare];
        }

        //now create the annotation...
        MapAnnotation *toAdd = [[MapAnnotation alloc]init];

        toAdd.coordinate = touchMapCoordinate;
        toAdd.title = annTitle;
        //toAdd.title = @"Title";
        toAdd.subtitle = @"Subtitle";

        [self.map addAnnotation:toAdd];
    }];
}
Community
  • 1
  • 1
Ernie
  • 89
  • 1
  • 11

1 Answers1

2

First, in the addPinToMap: method, addressLocation is called with currentLocation but currentLocation is never set. It's declared a few lines up but not set to any value.

So change:

CLLocation *currentLocation;

to:

CLLocation *currentLocation = [[CLLocation alloc] 
                                initWithLatitude:touchMapCoordinate.latitude 
                                longitude:touchMapCoordinate.longitude];


Second, even with this fix, it still won't work. The annotation's title will not get set because the reverseGeocodeLocation method's completion handler block will finish after the annotation has already been added (the block is asynchronous -- the code in addPinToMap: will not wait for it to finish).

You'll need to change the code around a bit and add the annotation inside the completion block when you actually have the geocoder result (whether success or failure).

Move the reverseGeocodeLocation call to the addPinToMap: method:

CLLocation *currentLocation = [[CLLocation alloc] 
                                initWithLatitude:touchMapCoordinate.latitude 
                                longitude:touchMapCoordinate.longitude];

[self.geocoder reverseGeocodeLocation:currentLocation completionHandler:^(NSArray *placemark, NSError *error) {

    //initialize the title to "unknown" in case geocode has failed...
    NSString *annTitle = @"Address unknown";

    //set the title if we got any placemarks...
    if (placemark.count > 0)
    {
        CLPlacemark *topResult = [placemark objectAtIndex:0];
        annTitle = [NSString stringWithFormat:@"%@ %@ %@ %@", topResult.country, topResult.locality, topResult.subLocality, topResult.thoroughfare];
    }

    //now create the annotation...
    MapAnnotation *toAdd = [[MapAnnotation alloc]init];

    toAdd.coordinate = touchMapCoordinate;
    toAdd.title = annTitle;
    toAdd.subtitle = @"Subtitle";

    [self.map addAnnotation:toAdd];
}];
  • Thats great, but I'm still having trouble displaying the pin, moving the code around doesn't help, if I block out the ‘reverseGeocodeLocation’ call the pin drops with the normal title and subtitle annotation as before. Any suggestions? – Ernie Dec 18 '13 at 20:53
  • You put the code shown in the answer in the addPinToMap method after the convertPoint line, right? Please add your updated code to the question. –  Dec 18 '13 at 20:58
  • That looks fine. To troubleshoot this, please do the following: 1) Put `NSLog(@"self.geocoder=%@", self.geocoder);` right before calling reverseGeocodeLocation. 2) Put `NSLog(@"geocoder error=%@", error);` inside the completion block right above the `NSString *annTitle = ...`. Let me know what the NSLogs print out. –  Dec 18 '13 at 21:58
  • NSLog printed: 2013-12-18 22:03:07.567 Track[20881:70b] self.geocoder=(null) – Ernie Dec 18 '13 at 22:05
  • The geocoder is null which explains why nothing happens. It's null because self.geocoder hasn't been created (alloc+init). Do you have code that creates it or is it only declared? –  Dec 18 '13 at 22:08
  • 1
    Iv now added 'self.geocoder = [[CLGeocoder alloc] init];' into '- (void)viewDidLoad' and its working great. Your help has been great, thank you. – Ernie Dec 18 '13 at 22:23
  • Was there a way to do this without putting the "add annotation" inside the completion block? This would cater for can you might be offline so you want the PIN Drop to occur onto the map, however it would be the case the reverse-geocoders wouldn't get a response. Is there a way to get a handle to the annotationView from the annotation? – Greg Nov 30 '15 at 01:38