我有一个tableView,有3列包含NSTextFieldCell。所有东西都被绑定填充。
计算其中一列单元格的文本,不能直接编辑。对于本专栏,我希望在单元格进入编辑模式时,显示按钮或自定义视图,而不是textField。换句话说,我想要一个NSCell在不被编辑时是一个NSTextFieldCell,和一个NSButtonCell(或自定义视图)在被编辑时。
有什么提示吗?
这是我尝试过的,但没有成功:
- <尝试strong> # 1 : 尝试strong>
我子类化了一个NSTextFieldCell
和覆盖fieldEditorForView:
如下所示=>问题是NSButton我返回不响应setDelegate:
和可能许多其他的东西。
- (NSTextView *)fieldEditorForView:(NSView *)aControlView {
NSTableView *tableView = (NSTableView *) aControlView;
// Manually computing column and row index for testing purposes
NSButton* button = [[NSButton alloc] initWithFrame:[tableView frameOfCellAtColumn:2 row:2]];
return (NSTextView *)button;
}
- <尝试strong> # 2 : 尝试strong>
子类NSTextFieldCell
和覆盖drawWithFrame: inView:
=>此方法仅用于在非编辑模式下绘制单元格。
- <尝试strong> # 3 : 尝试strong>
这个线索有一些潜力,但我显然在这里遗漏了一些东西。
实现windowWillReturnFieldEditor: toObject:
在我的窗口的委托,并返回一个自定义字段编辑器。我似乎在正确的轨道上,但我错过了一些东西。参数anObject从来不是我的自定义单元格(我仔细检查了,它在XIB中被正确定义)。
- (id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(id)anObject
{
if ([anObject isKindOfClass:[NSCellTextAndButtonAtEditTime class]])
{
NSLog(@"Going there");
NSButton* button = [[NSButton alloc] initWithFrame:CGRectMake(0, 0, 300, 20)];
button.title = @"test";
return button;
}
return nil;
}
在我看来,最好的方法是子类化NSTextView,为您的自定义单元格创建一个新的自定义字段编辑器,然后在您的自定义单元格中覆盖- (NSTextView *)fieldEditorForView:(NSView *)aControlView
以终止它。看起来期望NSTextFieldCell的编辑器是一个NSTextView几乎是强制性的,这可能就是为什么你尝试返回一个按钮失败的原因。我编写了这个简短的示例,它显示一个按钮,当您按下按钮时,它将文本字段单元格的值更新为当前时间并结束编辑。也许会有帮助:
@interface SOMyEditor : NSTextView
@end
@interface SOMyEditor ()
- (void)p_buttonPressed: (id)sender;
@end
@implementation SOMyEditor
- (id)initWithFrame:(NSRect)frameRect textContainer:(NSTextContainer *)container;
{
if (self = [super initWithFrame: frameRect textContainer:container])
{
NSButton* button = [[[NSButton alloc] initWithFrame: NSMakeRect(0,0,frameRect.size.width, frameRect.size.height)] autorelease];
button.title = @"Update Time!";
button.target = self;
button.action = @selector(p_buttonPressed:);
button.autoresizingMask |= NSViewWidthSizable | NSViewHeightSizable;
self.autoresizesSubviews = YES;
[self addSubview: button];
}
return self;
}
- (void)p_buttonPressed: (id)sender
{
NSString* string = [[NSDate date] description];
[self insertText: string];
[self didChangeText];
[self.window endEditingFor: self];
}
@end
然后让你的自定义单元格类做这样的事情:
@interface SOMyCustomTextFieldCell : NSTextFieldCell
@end
@interface SOMyCustomTextFieldCell ()
@property (retain) NSTextView* fieldEditor;
@end
@implementation SOMyCustomTextFieldCell
@synthesize fieldEditor = _fieldEditor;
- (NSTextView *)fieldEditorForView:(NSView *)aControlView
{
if (nil == _fieldEditor)
{
_fieldEditor = [[SOMyEditor alloc] init];
_fieldEditor.fieldEditor = YES;
}
return self.fieldEditor;
}
- (void)dealloc
{
[_fieldEditor release];
[super dealloc];
}
@end
这里有几个技巧。首先,如前所述,只要单元格是NSTextFieldCell,编辑器就必须是NSTextView的子类。子类化NSTextView带来了很多样板行为(你知道,所有你通常想要的行为,并从使用NSTextFieldCell进行编辑中免费获得)。如果你想让你的应用不表现得像有一个文本编辑器,你会做一些工作去禁用NSTextView的正常行为。
其次,当您覆盖- (NSTextView *)fieldEditorForView:(NSView *)aControlView
时,重要的是它在多个调用中为相同的单元格返回相同的字段编辑器。如果你只是在每次调用那个方法时创建一个新的NSTextView,它将无法正常工作。希望这对你有帮助!