Как я могу сделать NSTextField, содержащий атрибутивный текст, но копировать только простой текст - PullRequest
1 голос
/ 17 января 2020

У меня есть подкласс NSTextField, который использует подкласс NSTextFieldCell, который содержит приписанную строку. Мне бы хотелось, чтобы, когда пользователь копирует текст, который будет скопирован в монтажную панель без атрибутов.

Я попытался создать подкласс NSTextView, переопределить copy: и установить isFieldEditor в YES и вернуть этот новый редактор из метода клеток fieldEditorForView. Хотя это копирует только простой текст всякий раз, когда он используется, у меня есть текст, нарисованный на тексте, нарисованном на тексте (и так далее ...), и если основная приписанная строка изменяется другим элементом управления, редактор поля остается неизменным. Когда я не использую MyFieldEditor и позволяю подклассу NSTextFieldCell использовать реализацию по умолчанию, эта проблема не возникает.

Есть ли более простое решение этой проблемы?

Есть ли что-то дополнительное? что мне нужно переопределить или получить сообщения делегата для?

MyFieldCell.m

- (NSTextView *)fieldEditorForView:(NSView *)controlView
{
    MyFieldEditor *editor = [[MyFieldEditor alloc] init];
    [super setUpFieldEditorAttributes:editor];

    return editor;
}

MyFieldEditor.m

@implementation MyFieldEditor

- (instancetype)init
{
    if ( (self = [super init]) )
    {
        [self setFieldEditor:YES];
    }

    return self;
}

- (NSString *)selectedString
{
    return [[self string] substringWithRange:[self selectedRange]];
}

- (void)copy:(id)sender
{
    [[NSPasteboard generalPasteboard] setString:[self selectedString] forType:NSPasteboardTypeString];
}

@end

Примечание: я использую AR C .

Показать изображение проблемы

Drawing problem

Ответы [ 2 ]

1 голос
/ 17 января 2020

Пожалуйста, найдите ниже, что следует изменить. Протестировано и работает с Xcode 11.2.1 / macOS 10.15.2 без проблем с отображением.

a) Никаких пользовательских NSTextFieldCell и NSTextField не требуется, поэтому используется только по умолчанию

b) Изменить на следующее в MyFieldEditor.m

- (void)copy:(id)sender
{
    [NSPasteboard.generalPasteboard declareTypes:@[NSPasteboardTypeString] owner:self];
    [NSPasteboard.generalPasteboard setString:[self selectedString] forType:NSPasteboardTypeString];
}

c) Добавить метод делегата окна, заменяющий редактор полей для целевого текстового поля (это допустимый документированный способ предоставления пользовательских редакторов полей)

- (nullable id)windowWillReturnFieldEditor:(NSWindow *)sender toObject:(nullable id)client {
    if (client == self.textField) { // << in this case it is outlet
        return MyFieldEditor.new;
    }
    return nil;
}

Обновление:

Переопределение NSTextFieldCell, как показано ниже, и назначение его в XIB для целевого NSTextField вместо вышеупомянутого метода делегата NSWindow дает такое же допустимое поведение.

@interface MyTextCell: NSTextFieldCell
@end

@implementation MyTextCell
- (nullable NSTextView *)fieldEditorForView:(NSView *)controlView {
    id editor = MyFieldEditor.new;
    [super setUpFieldEditorAttributes:editor];
    return editor;
}
@end
0 голосов
/ 17 января 2020

Проблема fieldEditorForView: вызывается повторно. Каждый раз, когда он вызывается, он создает новый MyFieldEditor и не избавляется от старого редактора полей.

У NSWindow есть только один редактор полей, который он использует повторно. Я предполагаю, что любое поле редактора заданного типа должно быть создано только один раз и должно использоваться повторно. Таким образом, переменная stati c, ссылающаяся на редактор и проверку nil для создания, обеспечивает ленивый многократно используемый редактор.

@interface MyFieldCell: NSTextFieldCell
@end

@implementation MyFieldCell
- (nullable NSTextView *)fieldEditorForView:(NSView *)controlView
{
    static MyFieldEditor *kEditor;

    if ( kEditor ) { return kEditor; }
    kEditor = [[MyFieldEditor alloc] init];

    return kEditor;
}
@end

Было бы неплохо, если бы редактор мог стать слабым. К сожалению, NSTextView и его подклассы несовместимы со слабыми ссылками. Если у кого-то есть остроумная идея, я весь в ушах.

...