0
votes

I've read most of the other questions here, as well as read a lot, but I'm not finding an answer.

I'm using this code to create the buttons

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
    NSLog(@"called the MKAnnotView method, tag is: %i", self.tag);
    static NSString *s = @"ann";
    MKAnnotationView *pin = [mapView dequeueReusableAnnotationViewWithIdentifier:s];
    if (!pin) {
        pin = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:s];
        pin.canShowCallout = YES;
        pin.calloutOffset = CGPointMake(0, 0);
        UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
        button.tag=self.tag++;
        [button addTarget:self
                   action:@selector(viewDetails:)
                forControlEvents:UIControlEventTouchUpInside];
        pin.rightCalloutAccessoryView = button;

    }
    return pin;
}
-(void) viewDetails: (id) sender {
    UIButton *button = sender;
    NSLog(@"viewDetails called with button.tag: %i",button.tag);
    //[self performSegueWithIdentifier:@"detailView" sender:self];
}

I'm creating a variable amount of pins, in a specific order. When I create them, I get the expected output of "called the MKAnnotView method, tag is 0" then 1, 2, 3, etc.

The annotations are in a very specific order. Zeroth, first, second, so forth. I expect the buttons I created for each annotation to have a tag that fits their index, so that when I segue to the detailViewController, I know which item on the list needs to be pulled and the view populated.

That's not happening. The buttons are each getting randomly assigned tags that repeat. My last case had two tags with 3, and two with zero.

I cannot for the life of me understand why.

Any hints?

1
First, please see stackoverflow.com/questions/24215210/… which explains why viewForAnnotation cannot be expected to be called "in order".user467105
Remember that your pins can dequeue themselves so your tags can also repeat.William George
Second, please don't use button tags to identify annotations. See stackoverflow.com/questions/9462699/…, stackoverflow.com/questions/9797047/…, stackoverflow.com/questions/9876042/… for much better alternatives.user467105
Third, here's an example of doing a segue for a selected annotation: stackoverflow.com/questions/14805954/…user467105
Fourth, as pointed out by @WilliamGeorge, the code has a dequeue issue where an annotation gets a re-used view. You must update the view's annotation property when using a re-used view. See stackoverflow.com/questions/24702230/….user467105

1 Answers

0
votes

Based on comments to my question, the solution I came up with was implementing the following

- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
    self.tag = [self.annotArray indexOfObject:view.annotation];
    NSLog(@"calloutAccessoryControlTapped: annotation = %i", self.tag);
    [self performSegueWithIdentifier:@"ShowDetails" sender:self];
}

Whenever I create an annotation, I was already adding it to an annotArray property of this viewController for another use (as the view's built-in annotation array was not populating in a predictable manner)

my prepareForSegue method pulls self.tag and updates a property of the destinationViewController.