How to create a NSTextFieldCell, that in edit mode displays a custom view instead of NSTextField?

╄→尐↘猪︶ㄣ 提交于 2019-12-04 17:28:32

It seems to me the best way to do this is to subclass NSTextView, making a new custom field editor for your custom cell, and then override - (NSTextView *)fieldEditorForView:(NSView *)aControlView in your custom cell to vend it. It looks like the expectation that an NSTextFieldCell's editor be an NSTextView is pretty much mandatory, which is probably why your attempt to return a button failed. I cooked up this brief example which displays a button, and when you press the button, it updates the value of the text field cell to the current time and ends editing. Maybe it'll be helpful:

@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

Then have your custom cell class do something like this:

@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

There are a couple of tricks here. First, as mentioned, as long as the cell is an NSTextFieldCell, the editor will have to be a subclass of NSTextView. Subclassing NSTextView brings with it a LOT of boilerplate behavior (you know, all the behaviors you normally want and get for free from using NSTextFieldCell for editing). If you want your app to NOT behave as if there's a text editor, you're going to end up doing some work to disable the normal behaviors of NSTextView.

Secondly, when you override - (NSTextView *)fieldEditorForView:(NSView *)aControlView it's important that it return the same field editor for the same cell across multiple calls. If you just create a new NSTextView on every call to that method, it will not work right.

Hope this helps!

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!