[英]How can I make an NSTextField containing attributed text but only copy plain text
I have an NSTextField
subclass which uses a NSTextFieldCell
subclass which contains an attributed string.我有一个
NSTextField
子类,它使用一个包含属性字符串的NSTextFieldCell
子类。 I would like it if when the user copies text that it be copied to the pasteboard without the attributes.如果用户复制文本时将其复制到没有属性的粘贴板,我会喜欢它。
I have tried subclassing NSTextView
, overriding copy:
and setting isFieldEditor
to YES
and returning this new editor from the cells fieldEditorForView
method.我已经尝试子类化
NSTextView
,覆盖copy:
并将isFieldEditor
设置为YES
并从单元格fieldEditorForView
方法返回这个新编辑器。 While this copies only the plain text whenever it is used I have text drawn on text drawn on text (and so on ...) and if the underlying attributed string is changed by another control the field editor remains unmodified.虽然这只会在使用时复制纯文本,但我在文本上绘制的文本上绘制了文本(等等......),如果底层属性字符串被另一个控件更改,则字段编辑器保持不变。 When I do not use
MyFieldEditor
and let the NSTextFieldCell
subclass use the default implementation this issue does not occur.当我不使用
MyFieldEditor
并让NSTextFieldCell
子类使用默认实现时,不会发生此问题。
Is there a simpler solution to this problem?这个问题有更简单的解决方案吗?
Is there something additional that I need to override or receive delegate messages for?我需要覆盖或接收委托消息的其他内容吗?
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
Note: I am using ARC.注意:我正在使用 ARC。
Please find below what should be changed.请在下面找到应该更改的内容。 Tested & works with Xcode 11.2.1 / macOS 10.15.2 with no display issues.
已测试并与 Xcode 11.2.1 / macOS 10.15.2 配合使用,没有显示问题。
a) No custom NSTextFieldCell
and NSTextField
are needed, so used just default a) 不需要自定义
NSTextFieldCell
和NSTextField
,所以默认使用
b) Change to following in MyFieldEditor.m
b) 在
MyFieldEditor.m
更改为以下MyFieldEditor.m
- (void)copy:(id)sender
{
[NSPasteboard.generalPasteboard declareTypes:@[NSPasteboardTypeString] owner:self];
[NSPasteboard.generalPasteboard setString:[self selectedString] forType:NSPasteboardTypeString];
}
c) Add window delegate method substituting field editor for targeted textfield (this is the valid documented way to provide custom field editors) 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;
}
Update:更新:
Overriding NSTextFieldCell as below and assigning it in XIB for targeted NSTextField instead of above NSWindow delegate method gives the same valid behaviour.如下覆盖 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
The issue is fieldEditorForView:
is called repeatedly.问题是
fieldEditorForView:
被重复调用。 Every time it's called it creates a new MyFieldEditor
and doesn't get rid of the old field editor.每次调用它都会创建一个新的
MyFieldEditor
并且不会摆脱旧的字段编辑器。
An NSWindow
has only one field editor which it reuses. NSWindow
只有一个可以重用的字段编辑器。 I guess the assumption is that any field editor of a given type should only ever be created once and should be reused.我想假设是给定类型的任何字段编辑器都应该只创建一次并且应该被重用。 As such a static variable referencing the editor and a
nil
check to create provides a lazy reusable editor.因此,引用编辑器的静态变量和创建的
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
It would be nice if the editor could be made weak though.不过,如果编辑器可以变弱就好了。 Unfortunately
NSTextView
and its subclasses are incompatible with weak references.不幸的是
NSTextView
及其子类与弱引用不兼容。 If anyone has a cleaver idea around this I am all ears.如果有人对此有一个切肉刀的想法,我会全神贯注。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.