1

Suppose I have a button that I am adding to an annotation object in a mapview:

 AnnotationButton* rightButton = [AnnotationButton buttonWithType:UIButtonTypeDetailDisclosure];
            [rightButton addTarget:self
                            action:@selector(showDetails:)
                  forControlEvents:UIControlEventTouchUpInside];

You will notice that the button calls the function showDetails when it is clicked.

Show details is defined as - (void)showDetails:(id)sender; and takes a sender. Is there a way to send more variables, or associate a different sender? The reason is that I want the button clicked to tell me which annotation is associated with that button. Consider the annotation to be some other object which is available during the context where the button is created.

I thought about subclassing the UIButton class, and then storing additional information within it, but that seems like a hack.

Any ideas?

pyramation
  • 1,631
  • 4
  • 22
  • 35

2 Answers2

3

If this button is being used for the rightCalloutAccessoryView or leftCalloutAccessoryView of a MKAnnotationView, your map's delegate should receive the message mapView:annotationView:calloutAccessoryControlTapped: when the button is tapped. This hands you the MKAnnotationView instance that was tapped, which has an annotation property to give you the corresponding annotation. You should make use of that instead of trying to use an action on the button directly.

Anomie
  • 92,546
  • 13
  • 126
  • 145
2

No, there is no way to change what is sent to the action message. You can ask for two arguments, but they will be the button and the event that triggered it. To get what you want, you have two options (that I can think of now).

  1. Use the button's tag property. You can give each button a unique tag which identifiies the annotation, such as the index of the annotation in an array. Then it is easy to get the annotation in your showDetails: method.
  2. Subclass UIButton. There is nothing wrong with adding functionality to built in objects. All you need to add is a property to hold some object. Bonus: If you use a generic id type for the property and give it a generic name, such as representedObject, you can use it in other projects in the future too.
  3. from Anomie Use objc_setAssociatedObject to add a value to the buttons without subclassing. You will probably want to add a category to UIButton to make it easier to use.
ughoavgfhw
  • 39,734
  • 6
  • 101
  • 123
  • 1
    3. Use [objc_setAssociatedObject](http://stackoverflow.com/questions/5279884/how-to-add-userinfo-to-a-uialertview/5280117#5280117) (although if one considers subclassing UIButton a hack, one would probably consider that even more of a hack). – Anomie Mar 12 '11 at 03:36
  • @Anomie Thanks, I'll add that. Just remember that it requires iOS 4 or later. – ughoavgfhw Mar 12 '11 at 21:02
  • Are you sure? I seem to remember using it in the 3.1 days. – Anomie Mar 12 '11 at 21:31
  • You're right, its only OS X which has certain requirements to use it. I'll fix that in my post. – ughoavgfhw Mar 12 '11 at 21:35