子类化 UIButton 但无法访问我的属性

发布于 2024-09-03 00:17:17 字数 1186 浏览 4 评论 0原文

我创建了 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 类来设置该注释财产。我是否错过了一些非常明显的事情。感觉就像这样:)

提前感谢您为

罗斯提供的任何帮助

I've created a sub class 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 figured that I can then create this object and set the annotation object by doing the following:

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

localAnnotation is an NSObject but it is really an MKAnnotation. I can't see why this doesn't 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 can't see why it's even looking at UIButton because I've subclassed that so it should be looking at the MyDetailButton class to set that annotation property. Have I missed something really obvious. It feels like it :)

Thanks in advance for any help you can provide

Ross

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

世界如花海般美丽 2024-09-10 00:17:17

UIButton 是一个类簇,这意味着 Apple 的 buttonWithType: 实现可能看起来像这样

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

:一个 MyDetailButton 的实例,您将获得一个 PrivateDetailDisclosureButtonClass 的实例(或者 Apple 实际调用的任何名称)。

但请注意,如果您使用 UIButtonTypeCustom 调用子类,则可以让 buttonWithType 实例化子类(至少在运行 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

UIButton is a class cluster, which implies that Apple's implementation of buttonWithType: probably looks something like this:

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

So when you call [MyDetailButton buttonWithType:UIButtonTypeDetailDisclosure]; you don't get an instance of MyDetailButton, you get an instance of PrivateDetailDisclosureButtonClass (or whatever Apple actually calls it).

Note, however, that you can get buttonWithType to instantiate a subclass if you call it with UIButtonTypeCustom (At least in the 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
执笔绘流年 2024-09-10 00:17:17

我做了与原始海报相同的尝试,但似乎子类化 UIButton 来做这样的事情很困难。

我所做的是添加一个 UITextField 作为 UIButton 的子视图,这是一个 hack - 但现在对我有用。 UITextField 没有框架并且是隐藏的,但我可以在文本字段的文本属性中自由存储文本字符串。这就是我想做的......

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 的子视图添加到按钮。

哈哈 :-)

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

What I did, which is a hack - but works for me now, is add a UITextField as subview of the UIButton. The UITextField has no frame and is hidden, but I can freely store text strings in the textfield's text property. Which 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. It's ugly but...

Then later, to get that 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 tries to add a subview with tag 99 to the button.

Lol :-)

说好的呢 2024-09-10 00:17:17

该异常是因为您尝试从中获取注释的实际按钮不是类 MyDetailButton,它是一个 UIButton。验证您是否在 IB 中为该特定按钮设置了类。选择 IB 中的按钮并按 ⌘4 查看其标识,将 Class Identity 更改为 MyDetailButton。

That exception is because the actual button that you are trying to get the annotation from is not of class MyDetailButton, it is a UIButton. Verify that you set the class in IB for that particular button. Select the button in IB and press ⌘4 to see its identity, change the Class Identity to MyDetailButton.

唠甜嗑 2024-09-10 00:17:17

仅仅创建一个子类是不够的;还需要创建一个子类。子类不会取代其超类。同样,并非所有 UIControl、并非所有 UIView、并非所有 UIResponders、并非所有 NSObject 都具有 UIButton 的行为,并非所有 UIButton 都具有自定义子类的行为。

您需要的是您的子类的一个实例。您拥有的是 UIButton 的一个实例。

解决方案是使该实例成为您的子类的实例。如果您在 Interface Builder 中创建了该按钮,请选择该按钮并按 ⌘6,然后在此处更改实例的自定义类。如果您在代码中创建按钮,请将 alloc 消息发送到您的自定义子类,而不是直接发送到 UIButton。

Just making a subclass isn't enough; the subclass does not take the place of its superclass. The same way not all UIControls, not all UIViews, not all UIResponders, and not all NSObjects have the behavior of UIButton, not all UIButtons have the behavior of your custom subclass.

What you need is an instance of your subclass. What you have is an instance of UIButton.

The solution is to make that instance an instance of your subclass instead. If you created the button in Interface Builder, select the button and press ⌘6, then change the instance's Custom Class there. If you're creating the button in code, send your alloc message to your custom subclass, not directly to UIButton.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文