I have a map view with pins that when the user selects a pin it goes to a detail screen for that pin. I also have a table view that when the user selects an item it goes to the same type detail view.
I am adding the multiple pins in mapview through array. I have added button to the accessory view,
Here's the problem ...
when I tap the button pin selection takes him to the detail view for a different pin. But in the table view it still works fine..anyone pls help me with this...?
-(MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
MKPinAnnotationView *newAnnotation = nil;
if([annotation.title isEqualToString:@"You are here."])
{
newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"greenpin"];
newAnnotation.pinColor = MKPinAnnotationColorGreen;
}
else
{
newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:@"redpin"];
newAnnotation.pinColor = MKPinAnnotationColorRed;
UIButton *pinButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinButton.tag = indexvar;
[newAnnotation addSubview:pinButton];
newAnnotation.canShowCallout = YES;
newAnnotation.rightCalloutAccessoryView = pinButton;
newAnnotation.calloutOffset = CGPointMake(-5, 5);
indexvar++;
return newAnnotation;
[pinButton release];
}
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = YES;
return newAnnotation;
}
- (void)mapView:(MKMapView *)wikiMapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSInteger selectedIndex = ((UIButton *)control).tag;
NSLog(@"Property Index : %d ",selectedIndex);
DetailView = [[PropertyDetails alloc] initWithNibName:@"PropertyDetails" bundle:nil];
DetailView.propertyReference = [PropertyReferenceArr objectAtIndex:selectedIndex];
DetailView.propertyTitle = [propertyTitlesArr objectAtIndex:selectedIndex];
DetailView.propertyPrice = [propertyPriceArr objectAtIndex:selectedIndex];
DetailView.propertyBedrooms = [propertyBedroomsArr objectAtIndex:selectedIndex];
DetailView.propertyLatitude = [propertyLatitudesArr objectAtIndex:selectedIndex];
DetailView.propertyLongitude = [propertyLongitudesArr objectAtIndex:selectedIndex];
DetailView.propertyDefaultImage = [PropertyImageArr objectAtIndex:selectedIndex];
DetailView.propertyStatusId = [PropertyStatusArr objectAtIndex:selectedIndex];
[self.navigationController pushViewController:DetailView animated:YES];
[DetailView release];
}
In
viewForAnnotation
, the way you are setting the button tag using an ivar counter (indexvar
) assumes that the delegate method will get called only once and in the order that the annotations are added (which you are presumably doing in index order in some loop).The above assumption is not safe to make and not recommended. For example, the delegate method can definitely be called multiple times for the same annotation if the map view needs to re-display an annotation after it comes back into view because the user panned or zoomed back.
Instead of using button tags, embed the information you need into the annotation class itself and set that information when you add the annotation.
At a minimum (but still not recommended), what you could do is add a
propertyIndex
property to your annotation class and set it equal to the array index (of say thePropertyReferenceArr
array) you are creating the annotation from.A better solution, based on the numerous arrays you are using in
calloutAccessoryControlTapped
, is to create a proper class object to hold all the properties (of your real-estate "Properties" objects) and then have a single array to hold them (instead of a separate array for each attribute).This class could itself conform to
MKAnnotation
so you don't need to create a separate, explicit annotation object (you can just add the property object itself to the map).Then in
calloutAccessoryControlTapped
, you just castview.annotation
to your custom class and you instantly have access to all the annotation/Property data without any need for a tag or array index.The comment @naveen makes about your
addSubview
line is also valid (though it's not related to the issue). You should definitely remove that.Also, in
viewForAnnotation
, calling[pinButton release];
after thereturn
is pointless. That code will never run (which is good because if you put it before thereturn
, app will crash sincepinButton
is autoreleased).Rather then setting the button tag you can use the title or subtitle of the annotation for futher comparision or whatever you want
In your code you are using