2

I have a UIAlertView which appears as a confirmation when a user wants to delete a RegionAnnotation.

I'm having trouble figuring out how to access the RegionAnnotationView that called the UIAlertView which I need in order to delete the RegionAnnotation.

Here's my broken code - you can see where I'm trying to cast the AlertView's superview into a RegionAnnotationView (an admittedly bad idea).

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    if(buttonIndex==0)
    {
        NSLog(@"alertView.superview is a %@",alertView.superview);
        RegionAnnotationView *regionView = (RegionAnnotationView *)alertView.superview;
        RegionAnnotation *regionAnnotation = (RegionAnnotation *)regionView.annotation;

        [self.locationManager stopMonitoringForRegion:regionAnnotation.region];
        [regionView removeRadiusOverlay];
        [self.mapView removeAnnotation:regionAnnotation];    
    }

}
ari gold
  • 2,074
  • 3
  • 25
  • 51
  • Can using https://github.com/rsaunders100/UIAlertView-Blocks helps you ? Idea is to use blocks & not rely on delegate methods of UIAlertView (like clickedButtonAtIndex) – msk Aug 02 '12 at 18:55
  • Where is the alert view shown? Is the annotation "selected" before the user can delete it? –  Aug 02 '12 at 18:59
  • 1
    Or you can use objc_setAssociatedObject.. – msk Aug 02 '12 at 18:59
  • The annotation is indeed selected before the user can delete it. – ari gold Aug 02 '12 at 19:03
  • My guess is that I'm missing something simple because accessing the view that created the alert view must be one of the main points of alert views. – ari gold Aug 02 '12 at 19:04

1 Answers1

1

Since the annotation is selected before the user can delete it, you can get a reference to the annotation from the map view's selectedAnnotations property.

In the alert view delegate method, you can do something like this:

if (mapView.selectedAnnotations.count == 0)
{
    //shouldn't happen but just in case
}
else
{
    //since only one annotation can be selected at a time,
    //the one selected is at index 0...
    RegionAnnotation *regionAnnotation 
       = [mapView.selectedAnnotations objectAtIndex:0];

    //do something with the annotation...
}

If the annotation wasn't selected, another simple alternative is to use an ivar to hold a reference to the annotation that needs to be deleted.

Another option as MSK commented is to use objc_setAssociatedObject.

Regardless, using the superview assuming the view hierarchy is in a certain way is not a good idea.

  • I don't know where to post this but most of the fantastic answers I come across are from you. In fact, when I saw your name in the comments above I literally breathed a sigh of relief. – ari gold Aug 02 '12 at 19:32
  • While we're at it - any suggestions for learning to be an iOS ninja? – ari gold Aug 02 '12 at 19:33
  • For example, I've never come across anything like "objc_setAssociatedObject" and wouldn't know where to start.. – ari gold Aug 02 '12 at 19:37
  • Also, I was thinking of using an ivar but thought that there might be a more elegant solution. – ari gold Aug 02 '12 at 19:38
  • 1
    Thank you. I can suggest studying the documentation, the Apple sample apps, looking at other great SO answers, and lots of practice. –  Aug 02 '12 at 19:43
  • 1
    Regarding objc_setAssociatedObject, I believe that is the general, "elegant" solution for this case. [This answer by Anomie](http://stackoverflow.com/questions/5279884/how-to-add-userinfo-to-a-uialertview/5280117#5280117) gives a quick overview of how to use it. –  Aug 02 '12 at 19:46
  • Thanks again. I'm going to look over that link as soon as I get a few secs. You're the tops. – ari gold Aug 02 '12 at 19:53