我有NSPopUpButtonCell
的自定义子类,以便我可以覆盖其drawBezelWithFrame:inView:
方法。
目前,我必须使用initTextCell:pullsDown:
创建一个新实例,然后手动复制其所有属性。由于我可能遗漏了一些属性,这相当繁琐且容易出错。
我想知道我是否可以使用initWithCoder:
代替此任务。我想我应该能够将现有NSPopUpButtonCell
实例中的数据存档到NSCoder
对象中,例如进入NSKeyedArchiver
,然后将该数据归档到我的NSPopUpButtonCell
子类中。但我无法弄清楚如何实现这一目标。
答案 0 :(得分:1)
如果您的所有子类都是覆盖方法,即它不添加其他字段,那么您可以调整原始type
BitBltInstructions = packed record
MovEdiEdi: array[0..1] of byte; // $8B $FF
PushEbp: byte; // $55
MovEbpEsp: array[0..1] of byte; // $8B $EC
PushEcx: byte; // $51
end;
var
Instructions: BitBltInstructions;
bytes: array[0..Sizeof(BitBltInstructions)-1] of byte absolute Instructions;
i: Integer;
begin
Instructions.MovEdiEdi[0] := $8B;
Instructions.MovEdiEdi[1] := $FF;
Instructions.PushEbp := $55;
Instructions.MovEbpEsp[0] := $8B;
Instructions.MovEbpEsp[1] := $EC;
Instructions.PushEcx := $51;
for i := Low(bytes) to High(bytes) do
Memo1.Lines.Append(IntToHex(bytes[i], 2));
end;
的类或其副本,以便它成为您的子类的实例。
Apple使用这种技术实现KVO,在这种情况下使用动态生成的子类。如果你的情况是子类是静态的,那么使它更容易,代码的轮廓是:
NSPopupButtonCell
如果您可以安全地更改原始实例上的类,则根本不涉及对象创建或复制。
请记住,如果子类仅更改行为,则只能执行此操作。
有关其他说明,请参阅this answer。
HTH
答案 1 :(得分:0)
看起来我之前使用过错误的功能。这个问题很简单。
此代码将NSPopUpButtonCell的属性复制到其子类中,以便我可以覆盖其draw ...方法:
@interface MyPopup : NSPopUpButton
@end
@implementation MyPopup
- (instancetype)initWithCoder:(NSCoder *)coder {
self = [super initWithCoder:coder];
if (self) {
// Set up the archiver
NSMutableData *data = [NSMutableData data];
NSKeyedArchiver *arch = [[NSKeyedArchiver alloc] initForWritingWithMutableData:data];
// Archive the cell's properties
[self.cell encodeWithCoder:arch];
[arch finishEncoding];
// Set up the unarchiver
NSKeyedUnarchiver *ua = [[NSKeyedUnarchiver alloc] initForReadingWithData:data];
// Create a subclass of the cell's class, using the same properties
MyCell *newCell = [[MyCell alloc] initWithCoder:ua];
// Assign the new subclass object as the NSButton's cell.
self.cell = newCell;
}
return self;
}
另一种更清洁,使用自定义NSButtonCell子类的方法如下所示:Using full width of NSPopupButton for text, no arrows