簡體   English   中英

如何制作包含屬性文本但僅復制純文本的 NSTextField

[英]How can I make an NSTextField containing attributed text but only copy plain text

我有一個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

注意:我正在使用 ARC。

顯示問題圖像

繪圖問題

請在下面找到應該更改的內容。 已測試並與 Xcode 11.2.1 / macOS 10.15.2 配合使用,沒有顯示問題。

a) 不需要自定義NSTextFieldCellNSTextField ,所以默認使用

b) 在MyFieldEditor.m更改為以下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

問題是fieldEditorForView:被重復調用。 每次調用它都會創建一個新的MyFieldEditor並且不會擺脫舊的字段編輯器。

NSWindow只有一個可以重用的字段編輯器。 我想假設是給定類型的任何字段編輯器都應該只創建一次並且應該被重用。 因此,引用編輯器的靜態變量和創建的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及其子類與弱引用不兼容。 如果有人對此有一個切肉刀的想法,我會全神貫注。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM