How can you intercept pasting into a NSTextView to

2019-02-16 20:00发布

问题:

I'm trying to create a simple NSTextView-based window for simple WYSIWYG editing. However, I only want to allow certain types of formatting (e.g. Bold, Italic, Underline and a single heading type but no colors or different fonts.)

The issue is if I simply use NSTextView, someone can create or copy formatted text in another program, then simply paste it into that view and all that formatting goes with it, allowing things I'm not allowing, such as different fonts, colors, etc.

At best, I want to automatically strip out any formatting that my application doesn't support. At worst, I want to simply intercept the paste and change it to plain-text although they would have to then manually re-format it. But that's preferable to invalid formatting.

Note: Something similar has been asked here on SO multiple times, but they're usually referring to the web or using JavaScript/JQuery. I am specifically referring to using NSTextView in a Mac app so please, before simply marking this as a duplicate, make sure that's what the other question refers to. Thank you.

回答1:

In your NSTextView subclass:

  override func paste(_ sender: Any?) {
     pasteAsPlainText(sender)
  }


回答2:

[Edit: see Joshua Nozzi's comment!]

One possible solution would be to make your NSTextView implement this template method:

- (void)paste:(id)sender {
    NSPasteboard *pb = [NSPasteboard generalPasteboard];
    //receive formatted string from pasteboard
    //remove formatting from string
    //put back plaintext string into pasteboard
    [super paste:sender];
    //put back initial formatted string
}

This way you don't have to handle any of the actual insertion/pasting but can mess with the pasteboard before the actual pasting.

You might also want to look into these methods of NSTextView dealing with the Pasteboard:

  • preferredPasteboardTypeFromArray:restrictedToTypesFromArray:
  • readSelectionFromPasteboard:
  • readSelectionFromPasteboard:type:
  • readablePasteboardTypes
  • writablePasteboardTypes
  • writeSelectionToPasteboard:type:
  • writeSelectionToPasteboard:types:
  • validRequestorForSendType:returnType: