UIButton subclassification, but not access to my properties

I created a subclass of UIButton:

// // DetailButton.h #import <Foundation/Foundation.h> #import <MapKit/MapKit.h> @interface MyDetailButton : UIButton { NSObject *annotation; } @property (nonatomic, retain) NSObject *annotation; @end // // DetailButton.m // #import "MyDetailButton.h" @implementation MyDetailButton @synthesize annotation; @end 

I decided that I could then create this object and set up the annotation object by doing the following:

 MyDetailButton* rightButton = [MyDetailButton buttonWithType:UIButtonTypeDetailDisclosure]; rightButton.annotation = localAnnotation; 

localAnnation is an NSObject, but it really is MKAnnotation. I do not understand why this does not work, but at runtime I get this error:

  2010-05-27 10:37:29.214 DonorMapProto1[5241:207] *** -[UIButton annotation]: unrecognized selector sent to instance 0x445a190 2010-05-27 10:37:29.215 DonorMapProto1[5241:207] *** Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '*** -[UIButton annotation]: unrecognized selector sent to instance 0x445a190' 

I don’t understand why he even looks at UIButton, because I subclassed it so that he looked at the MyDetailButton class to set this annotation property. I missed something really obvious. It feels like that :)

Thanks in advance for any help you can provide.

Ross

0
source share
4 answers

UIButton is a class cluster, from which it follows that the Apple implementation of buttonWithType: probably looks something like this:

 +(id)buttonWithType:(UIButtonType)t { switch (t) { case UIButtonTypeDetailDisclosure: return [[[PrivateDetailDisclosureButtonClass alloc] init] autorelease]; case ... } } 

Therefore, when you call [MyDetailButton buttonWithType:UIButtonTypeDetailDisclosure]; , you are not getting an instance of MyDetailButton , you are getting an instance of PrivateDetailDisclosureButtonClass (or that Apple actually calls it).

Note, however, that you can get buttonWithType to create a subclass if you call it using UIButtonTypeCustom (at least in a simulator running v3.0):

 // LGButton is a straightforward subclass of UIButton LGButton *testBtn = [LGButton buttonWithType:UIButtonTypeCustom]; LGButton *testBtn2 = [LGButton buttonWithType:UIButtonTypeDetailDisclosure]; NSLog(@"testBtn: %@, testBtn2: %@", [testBtn class], [testBtn2 class]); // Output: testBtn: LGButton, testBtn2: UIButton 
+14
source

I made the same attempt as the original poster, but it seems that subclassing UIButton to do something like this is complicated.

What I did was hack, but now it works for me, adds a UITextField as a UIButton subitem. UITextField has no frame and is hidden, but I can freely store text strings in the text property of a text field. This is what I wanted to do ...

 UITextField* tf = [[UITextField alloc] init]; tf.text = @"the text that I wanna store"; tf.hidden = YES; tf.tag = TAGOFBUTTONSUBTEXTFIELD; [previouslyCreatedButton addSubview:tf]; [tf release]; 

I defined TAGOFBUTTONSUBTEXTFIELD as 99 somewhere. Global. This is ugly, but ...

Then, to get this text string, use something like this:

 +(NSString*)getStoredStringFromButton:(UIButton*)button { UITextField* tf = (UITextField*)[button viewWithTag:TAGOFBUTTONSUBTEXTFIELD]; return tf.text; } 

So, this assumes that no one else is trying to add a preview with tag 99 to the button.

Lol :-)

+2
source

This exception is that the actual button with which you are trying to get the annotation is not of the MyDetailButton class, it is UIButton. Make sure you set the class in IB for this particular button. Select the button in IB and press ⌘4 to see its identity, change the class identifier to MyDetailButton.

+1
source

Just subclassing is not enough; a subclass does not replace its superclass. Similarly, not all UIControls, not all UIViews, not all UIResponders, and not all NSObjects have UIButton behavior, not all UIButtons have your custom subclass behavior.

You need an instance of your subclass. You have an instance of UIButton.

The solution is to make this instance an instance of your subclass. If you created the button in Interface Builder, select the button and press ⌘6, and then change the instance of Custom Class. If you create a button in code, send the message alloc to your own subclass, not directly to UIButton.

0
source

Source: https://habr.com/ru/post/1342420/


All Articles