我有一个 NSTextField
子类,它使用包含属性字符串的 NSTextFieldCell
子类。我希望当用户复制文本时将其复制到没有属性的粘贴板。
我尝试对 NSTextView
进行子类化,覆盖 copy:
并将 isFieldEditor
设置为 YES
并返回这个新编辑器来自单元格 fieldEditorForView
方法。虽然这在使用时仅复制纯文本,但我在文本上绘制的文本上绘制了文本(等等......),并且如果底层属性字符串被另一个控件更改,则字段编辑器保持不变。当我不使用 MyFieldEditor
并让 NSTextFieldCell
子类使用默认实现时,不会出现此问题。
有没有更简单的方法来解决这个问题?
是否还有其他需要我覆盖或接收委托(delegate)消息的内容?
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
注意:我使用的是 ARC。
显示问题图片
最佳答案
请在下面找到应该更改的内容。 经过测试,可与 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) 添加窗口委托(delegate)方法,用字段编辑器替换目标文本字段(这是提供自定义字段编辑器的有效记录方法)
- (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 委托(delegate)方法,可以提供相同的有效行为。
@interface MyTextCell: NSTextFieldCell
@end
@implementation MyTextCell
- (nullable NSTextView *)fieldEditorForView:(NSView *)controlView {
id editor = MyFieldEditor.new;
[super setUpFieldEditorAttributes:editor];
return editor;
}
@end
关于objective-c - 如何制作包含属性文本但仅复制纯文本的 NSTextField,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59782310/