Как создать NSTextFieldCell, который в режиме редактирования отображает пользовательское представление вместо NSTextField? - PullRequest
2 голосов
/ 01 августа 2011

У меня есть tableView с 3 столбцами, содержащими NSTextFieldCell.Все заполнено привязками.

Текст ячеек одного из столбцов вычисляется и не редактируется напрямую.Для этого столбца мне бы хотелось, чтобы , когда ячейка переходит в режим редактирования , чтобы отображало кнопку или пользовательский вид вместо textField .
Сказанный другим способом, яхотите NSCell , который является NSTextFieldCell , когда он не редактируется, и NSButtonCell (или пользовательский вид), когда он редактируется.

Любойнамек, чтобы перейти к этому?


Вот что я пытался, но безуспешно:

  • Попробуйте # 1 :

Я подклассифицировал 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;
}

1 Ответ

2 голосов
/ 15 января 2012

Мне кажется, что лучший способ сделать это - создать подкласс 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 при каждом вызове этого метода, он не будет работать правильно.

Надеюсь, это поможет!

...