Reputation: 15669
I am displaying several pins on map just like this:
for (int i = 0; i < points.count; i++) {
if([[[points objectAtIndex:i] objectForKey:@"lat"] class] != [NSNull class]) {
southWest.latitude = MAX(southWest.latitude , [[[points objectAtIndex:i] objectForKey:@"lat"] doubleValue]);
southWest.longitude = MIN(southWest.longitude, [[[points objectAtIndex:i] objectForKey:@"lon"] doubleValue]);
northEast.latitude = MIN(northEast.latitude, [[[points objectAtIndex:i] objectForKey:@"lat"] doubleValue]);
northEast.longitude = MAX(northEast.longitude, [[[points objectAtIndex:i] objectForKey:@"lon"] doubleValue]);
pin.latitude = [[[points objectAtIndex:i] objectForKey:@"lat"] doubleValue];
pin.longitude = [[[points objectAtIndex:i] objectForKey:@"lon"] doubleValue];
CarPin *cPin = [[CarPin alloc] initWithName:[[self.brain.cars objectAtIndex:i] objectForKey:@"name"] state:[self getStateStringFor:[[[points objectAtIndex:i] objectForKey:@"state"] intValue]] coordinate:pin];
cPin.state = [[[points objectAtIndex:i] objectForKey:@"state"] intValue];
cPin.carID = [[points objectAtIndex:i] objectForKey:@"objekt_id"];
[self.mapView addAnnotation:cPin];
}
}
CLLocation *locSouthWest = [[CLLocation alloc] initWithLatitude:southWest.latitude longitude:southWest.longitude];
CLLocation *locNorthEast = [[CLLocation alloc] initWithLatitude:northEast.latitude longitude:northEast.longitude];
CLLocationDistance meters = [locSouthWest distanceFromLocation:locNorthEast];
MKCoordinateRegion region;
region.center.latitude = (southWest.latitude + northEast.latitude) / 2.0;
region.center.longitude = (southWest.longitude + northEast.longitude) / 2.0;
region.span.latitudeDelta = meters / 111319.5;
region.span.longitudeDelta = 0.0;
[self.mapView setRegion:[self.mapView regionThatFits:region] animated:YES];
THEN I choose "look" of each pin like this:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString *identifier = @"CarPin";
if ([annotation isKindOfClass:[CarPin class]]) {
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
if (((CarPin *)annotation).state == 1) {
annotationView.pinColor = MKPinAnnotationColorGreen;
} else {
annotationView.pinColor = MKPinAnnotationColorRed;
}
return annotationView;
}
return nil;
}
I also set the delegate
[self.mapView setDelegate:self];
BUT, when I click on each pin, I get no bubble displayed on screen with details! Anybody experiencing the same?
Upvotes: 2
Views: 800
Reputation:
Simply implementing the title
property is not enough.
You have to make sure that title
is not returning nil
or blank.
If it is, the annotation view will not display a callout even if canShowCallout
is set to YES
.
Unrelated to your issue but regarding this line:
region.span.latitudeDelta = meters / 111319.5;
This is not recommended and unnecessary for at least three reasons:
Calculating the meter distance between the two corners (for which you have the latitude and longitude in degrees and then converting those meters back to degrees) is unecessary because latitudeDelta
and longitudeDelta
is simply the difference in degrees between the top/bottom or left/right. So all you have to do is:
region.span.latitudeDelta = fabs(southWest.latitude - northEast.latitude);
This is the change I would recommend in your case.
The value you are dividing by to convert meters to degrees (111319.5
) will only be accurate at the equator.
If you want to specify a region based on meters, instead of calculating the span in degrees manually, it's much better and easier to use the built-in MKCoordinateRegionMakeWithDistance
function:
CLLocationCoordinate2D center = CLLocationCoordinate2DMake (lat, long);
CLLocationDistance latMeters = 5000; //5 km
CLLocationDistance lonMeters = 5000; //5 km
MKCoordinateRegion region
= MKCoordinateRegionMakeWithDistance (center, latMeters, lonMeters);
Also, calling regionThatFits
is unnecessary in your case because the setRegion
will already do this itself with whatever region you pass it. The regionThatFits
method is used when you want to know (without actually changing the region) what the map view would adjust the region to given a certain region.
Upvotes: 2