Objective c 子类化NSTextField

Objective c 子类化NSTextField,objective-c,cocoa,xcode,subclass,nstextfield,Objective C,Cocoa,Xcode,Subclass,Nstextfield,考虑到我每天都要处理的复杂事情,这似乎是一个“我到底做错了什么,看起来很简单?”的场景 我想对NSTextField进行子类化,以更改背景颜色和文本颜色。为了简单起见(并帮助任何以前从未子类化过任何东西的人),下面是我的(简化)子类MyNSTextFieldSubclass 第1步: 创建子类文件: 首先是头文件 @interface MyTextFieldSubclass : NSTextField { } @end 和方法文件 @implementation MyTextFieldSub

考虑到我每天都要处理的复杂事情,这似乎是一个“我到底做错了什么,看起来很简单?”的场景

我想对
NSTextField
进行子类化,以更改背景颜色和文本颜色。为了简单起见(并帮助任何以前从未子类化过任何东西的人),下面是我的(简化)子类
MyNSTextFieldSubclass

第1步:

创建子类文件:

首先是头文件

@interface MyTextFieldSubclass : NSTextField {
}

@end
和方法文件

@implementation MyTextFieldSubclass

-(NSColor *)backgroundColor {
    return [NSColor redColor];
}

-(NSColor *)textColor {
    return [NSColor yellowColor];
}

@end
第二步:

NSTextField
拖动到Interface Builder中的窗口中,在inspector中选择
Identity
选项卡,然后选择类
MyTextFieldSubclass

第三步:

保存IB文件,构建并运行应用程序

问题

运行构建时,文本字段不反映颜色子类化。但是,我知道子类正在被调用,因为如果我添加以下方法,它会在文本更改时被调用

-(void)textDidChange:(NSNotification *)notification {
    NSLog(@"My text changed");
}
那么,为什么文本字段上不会发生颜色变化呢

我知道我可以在IB中设置颜色,但是对于那些处理过很多UI元素的人来说,它们都需要相同的样式,子类化让生活变得更加简单

具有讽刺意味的是,我以前从未对
NSTextField
进行过子类化,而这一个让我感到困惑

和往常一样,非常感谢所有的帮助。我相信这将是一个“Doh!”的时刻——只是现在看不见树木(再加上我因为一大早看了太多世界杯足球赛而筋疲力尽,这对我毫无帮助)

==解决方案===

正如Jaanus所提供的,解决方案是将其放入
viewWillDraw
方法中。因此,我的(简化)方法现在如下所示:

@implementation MyTextFieldSubclass

-(void)viewWillDraw {
    [super setBackgroundColor:[NSColor redColor]];
    [super setTextColor:[NSColor yellowColor]];
}

@end

谢谢大家的帮助。

由于您可以在Interface Builder的属性检查器中设置NSTextField的背景色和文本色,或者您可以通过编程方式使用
-setBackgroundColor:
-setTextColor:
,因此不需要创建子类来更改颜色。看起来太过分了


编辑:如果设置大量元素的样式是个问题,您是否考虑过使用颜色绑定?上一次我检查时,NSTextField没有背景颜色的绑定,但是因为您使用的是子类,所以您可以。普雷斯顿是正确的:要更改颜色,您不应该使用子类,只需更改textfield属性即可。(哦,这是NSTextfield,它可能没有属性……好吧,只需使用getter和setter方法或在IB中正确配置它即可。)

至于

那么,为什么文本字段上不会发生颜色变化呢

因为你混淆了接受者和接受者。在您的子类中,您已经将它们实现为getter,它们只返回一种颜色。实际上,它们应该是setter函数(这就是它们在NSTextfield内部的实现方式):你给它们传递一种颜色,然后它们去摆弄NSTextfield内部的任何东西,以使颜色发生变化

编辑:好的,如果你是子类化的,因为你总是想设置一个特定的颜色,你会做如下的事情

-(void)viewDidAppear { // or whatever is the Appkit equivalent
    [super setBackgroundColor:...];
}

谢谢你,普雷斯顿,但有一个需要子类。在IB中设置属性意味着您必须对每个字段进行设置。此外,当直接在IB中设置时,允许用户动态更改设置变得很难管理。此外,在每个视图上执行
-setTextColor
和background操作意味着管理一整套设置。子类化消除了所有这些问题。此外,还允许将来在一个位置进行更新,而不必接触许多文件。这是子类化的理想用法。您考虑过对颜色使用绑定吗?老实说,没有,但这可能是一种选择。一般来说,我尽量避免使用IB的绑定,因为在跟踪使用源代码控制软件的开发人员之间的代码更改时,这会使工作变得复杂。我想理论上我可以绑定颜色,但我是否仍然需要对每个文本字段进行子类化或定义绑定?Preston-Jaanus提出了一个可行的解决方案(我将更新上面的帖子以反映变化)。谢谢你的反馈。我会将绑定策略保留到另一天!:-)Jaanus,我认为Preston的答案不适合在大型应用程序中管理大量文本字段(因为我在对他的答案的评论中详细说明了原因)。我同意这是可行的,也是一种方法,但它并不能解决管理大量需要完全相同样式的文本字段的问题。据我所知,上面示例中的子类应该在使用该子类的任何文本字段中返回“红色”作为背景,返回“黄色”作为文本。当我可以强制在getter.Jaanus中返回颜色时,我不需要调用setter-您的编辑在消息中被交叉了!你明白了。我把它放在
-(void)viewWillDraw
方法中。工作得很好。非常感谢。