2

我有一个 tableView,有 3 列包含 NSTextFieldCell。一切都充满了绑定。

其中一列的单元格的文本是计算出来的,不能直接编辑。对于本专栏,我希望当单元格进入编辑模式时,显示一个按钮或自定义视图,而不是 textField
换句话说,我想要一个NSCell ,它在不被编辑时是一个NSTextFieldCell ,而在被编辑时是一个NSButtonCell(或自定义视图)。

有什么提示可以继续这个吗?


这是我尝试过的,但没有成功:

  • 尝试#1

我将 a 子类化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;
}
  • 尝试#2

子类NSTextFieldCell和覆盖drawWithFrame: inView:=> 此方法仅用于在不处于编辑模式时绘制单元格。

  • 尝试#3

这条线索有一些潜力,但我显然在这里遗漏了一些东西。在我的窗口委托中
实现,并返回一个自定义字段编辑器。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;
}
4

1 回答 1

2

在我看来,最好的方法是继承 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,它将无法正常工作。

希望这可以帮助!

于 2012-01-14T22:42:39.720 回答