Show address in annotation when pin is dropped on map

2.3k views Asked by At

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

There are 1 answers

7
AudioBubble On BEST ANSWER

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