3

I am trying to access the copy, cut, and paste methods of a NSTextField instance in its window delegate so I can customize these methods. I find that unlike tableViews and textViews, the textfield's copy, paste and cut actions are not responsive in the delegate. My understanding is that all text controls share the window's field editor yet this does not seem to be the case.

I thought perhaps the TextField's field editor was not being shared with the window delegate, however I did some testing I see that as I am typing in control, those field editors are identical--very strange.

My current work-around is to use a subclass instance of NSTextView where the copy and paste action methods respond as needed. This, however, has its own issues and I was hoping there was some way to get NSTextFields to work as expected.

Antony
  • 187
  • 4
  • 15
  • Is it OK for you to subclass NSTextField and take over a couple of methods? – Jean Apr 01 '13 at 18:17
  • Thanks Jean, I already tried this to no avail. Just as the case using the window's delegate, there is no response to those action methods. – Antony Apr 01 '13 at 23:53

2 Answers2

4

A nstextfield does not have copy and paste functions. Those are only found in nstextview. the catch is that when a textfield is edited it opens up a textview called a fieldeditor during the editing and sets that as the first responder.

How to solve:

Each text field has a cell as a child connected to it (called cell in the picture but should be named more appropriately, e.g. CustomTextEditor):

enter image description here

The cell has a method for implementing a custom field editor called fieldEditorForView:

class cell: NSTextFieldCell {

    var editor: NSTextView

    override func fieldEditorForView(aControlView: NSView) -> NSTextView? {
        if editor == nil {
            editor = ESPasteView()
        }
        return editor
    }

}

This above function allows you to provide your own custom NSTextView subclass:

class ESPasteView: NSTextView, NSTextViewDelegate {

    override func paste(sender: AnyObject?) {
        Swift.print("user tries to paste")
        super.pasteAsPlainText(nil)
    }

}

Credit to:

How to disable context menus with right mouse click in an NSTextField (Cocoa)?

and Ken Thomases who pointed out the field editor.

Thomas Tempelmann
  • 11,045
  • 8
  • 74
  • 149
jiminybob99
  • 857
  • 1
  • 8
  • 15
  • Thank you, I used this technique to customize the text copied to the pasteboard when copying from an `NSTextField`. I override the `copy(_:)` method of the field editor and set the customized text on the pasteboard manually within the overridden implementation. – Andrew Feb 04 '18 at 09:06
  • 1
    Should be considered that the method: `fieldEditor(for controlView: NSView)` will be called several times so it would be better to store a reference to the `NSTextView` and avoid creating a new instance every time. – vicegax Feb 16 '21 at 16:54
-1

Maybe you could take a look at NSTextField's:

- (BOOL)writeSelectionToPasteboard:(NSPasteboard *)pboard type:(NSString *)type;
- (BOOL)readSelectionFromPasteboard:(NSPasteboard *)pboard type:(NSString *)type;

This would allow you to intercept the call customize the response.

Jean
  • 7,623
  • 6
  • 43
  • 58
  • 2
    Thanks again Jean. I'm not sure these methods are valid for NSTextField although I see them listed for NSTextView. Nevertheless, I would have tested them anyway except that the reason for customizing the copy method was to perform a deep copy of a coreData entity. I'm sure the text editor would only provide the pasteboard with a string--not the object ID I am after. – Antony Apr 01 '13 at 23:58
  • @Antony I have never used them, but both selectors are defined as an NSObject category `NSObject(NSServicesRequests)`. Also, the suggested solution seemed to work for the OP of [this thread](https://groups.google.com/forum/?fromgroups=#!topic/cocoa-unbound/pWYjtkv7x7M). – Jean Apr 02 '13 at 07:53
  • Jean, thanks for your persistance: I overlooked that your suggested methods applied to the NSObject class. Nevertheless, I was not able to get the methods to work within my NSTextField subclass or delegate. My failure is probably due to not implementing the service protocol correctly. In any case, having to provide a service in order to intercede NSTextField's copy and paste methods seems rather heavy-handed to me. – Antony Apr 03 '13 at 04:37
  • It depends. What kind of customization are you looking for? – Jean Apr 03 '13 at 08:45
  • I thought services are for providing interactions with other applications. I'm trying to provide a way to move data via a deep copy of coredata objects within my own application. In other words, I want the user to be able to copy a sentence within a NSTextField that represents a data graph so that when it's pasted elsewhere within my application, produces the underlying data graph at that new location. I know I can do this by copying NSManagedObjectID's to the pasteboard. – Antony Apr 05 '13 at 04:06
  • I notice that Jean's reply above bears a check-mark, however even if I were able to implement 'writeSelectionToPasteboard' method for a NSTextField subclass, this would not help for my case where the user copy, paste, and cut actions need to be detected. – Antony Apr 21 '13 at 19:33
  • @Antony Every answer to your questions have a white check mark. Only those you accept have a green one. **Don't worry** *only you can accept the answer*. Nobody does it for you, and this answer was not accepted. Though it did not help you, this is the way to go and I leave the answer here so it can help others. I hope somebody else will be able to give you what you seek, but I fear their answer may not be very different since there is not many possibilities to solve your issue. – Jean Apr 21 '13 at 19:35
  • I appreciate any attempt to answer my questions--sorry for the misunderstanding. I just didn't want someone to eroneously think that there was a solution here. I am a newbie. – Antony Sep 01 '13 at 03:23
  • Have you found the answer to your question? If so, you can add it here and mark it as solved. On stackoverflow, it's OK to answer your own questions. You are even encouraged to do so. – Jean Sep 25 '13 at 06:51
  • Although I had not found a solution yet, the solution posted above may well be the fix I was looking for. – Antony Aug 11 '16 at 22:39
  • The linked thread's solution is about `NSTextView`, not `NSTextField`. `NSTextField` does not have these members. This answer is wrong, sorry. – Lightness Races in Orbit Jan 14 '20 at 12:20