我创建了一个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
我认为我可以通过执行以下操作来创建此对象并设置注释对象:
MyDetailButton* rightButton = [MyDetailButton buttonWithType:UIButtonTypeDetailDisclosure];
rightButton.annotation = localAnnotation;
localAnnotation是一个NSObject,但它实际上是一个MKAnnotation。我不明白为什么这不起作用,但在运行时我得到这个错误:
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'
我不明白为什么它甚至会查看UIButton,因为我已经将其子类化了,所以应该查看MyDetailButton类来设置该注释属性。我错过了一些非常明显的东西。感觉就好了:))
提前感谢您提供的任何帮助
罗斯
答案 0 :(得分:14)
UIButton是一个类集群,这意味着Apple的buttonWithType:
实现可能看起来像这样:
+(id)buttonWithType:(UIButtonType)t {
switch (t) {
case UIButtonTypeDetailDisclosure:
return [[[PrivateDetailDisclosureButtonClass alloc] init] autorelease];
case ...
}
}
因此,当您致电[MyDetailButton buttonWithType:UIButtonTypeDetailDisclosure];
时,您没有获得MyDetailButton
的实例,您会获得PrivateDetailDisclosureButtonClass
的实例(或Apple实际上称之为的任何实例)。
但是,请注意,如果使用buttonWithType
调用它,可以获取UIButtonTypeCustom
实例化子类(至少在运行v3.0的模拟器中):< / p>
// 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
答案 1 :(得分:2)
我做了与原始海报相同的尝试,但似乎将UIButton子类化做这样的事情很难。
我做了什么,这是一个黑客 - 但现在对我有用,是添加一个UITextField作为UIButton的子视图。 UITextField没有框架并且是隐藏的,但我可以在textfield的text属性中自由存储文本字符串。这就是我想要做的......
UITextField* tf = [[UITextField alloc] init];
tf.text = @"the text that I wanna store";
tf.hidden = YES;
tf.tag = TAGOFBUTTONSUBTEXTFIELD;
[previouslyCreatedButton addSubview:tf];
[tf release];
我在某处将TAGOFBUTTONSUBTEXTFIELD定义为99。全球。这很难看但是......
然后,要使用这样的文本字符串:
+(NSString*)getStoredStringFromButton:(UIButton*)button {
UITextField* tf = (UITextField*)[button viewWithTag:TAGOFBUTTONSUBTEXTFIELD];
return tf.text;
}
因此,假设没有其他人尝试将带有标记99的子视图添加到按钮中。
哈哈: - )
答案 2 :(得分:1)
这个例外是因为你试图从中获取注释的实际按钮是MyDetailButton类的不是,它是一个UIButton。验证是否在IB中为该特定按钮设置了类。选择IB中的按钮,然后按⌘4查看其身份,将Class Identity更改为MyDetailButton。
答案 3 :(得分:0)
仅仅制作一个子类是不够的;子类不取代它的超类。同样的方式并非所有的UIControl,不是所有的UIViews,不是所有的UIResponder,也不是所有的NSObject都有UIButton的行为,并不是所有的UIButton都有自定义子类的行为。
您需要的是您的子类的实例。你拥有的是UIButton的一个实例。
解决方案是将该实例改为子类的实例。如果在Interface Builder中创建了按钮,请选择按钮并按⌘6,然后在那里更改实例的自定义类。如果您在代码中创建按钮,请将alloc
消息发送到自定义子类,而不是直接发送到UIButton。