How to override [NSTextField paste:]

  • Is there a way to override the -paste: method of NSTextField, other than subclassing?

    I have a situation where I want to handle paste for several related text entry fields at once. I have implemented -paste: in the controller for these, but of course it goes to first responder which is the text field itself (or its editor) which isn't what I want. Subclassing the field is an option, but because of the Field Editor, I'm not sure it's what is really needed.

    --Graham
  • On Jun 14, 2012, at 11:04 PM, Graham Cox wrote:

    > Is there a way to override the -paste: method of NSTextField, other than subclassing?
    >
    > I have a situation where I want to handle paste for several related text entry fields at once. I have implemented -paste: in the controller for these, but of course it goes to first responder which is the text field itself (or its editor) which isn't what I want. Subclassing the field is an option, but because of the Field Editor, I'm not sure it's what is really needed.

    -paste: is handled by NSTextView (by virtue of being an NSText subclass), not by the NSTextField for which it is acting as a field editor.

    Your best bet is probably to retarget the Paste menu item to use a different selector that is picked up by your window controller. Then also implement this selector on your NSApplication delegate (or subclass) to re-send -paste: as a backstop in case an instance of your window controller isn't in the responder chain.

    // Warning: composed in Mail.app

    @implementation MyWindowController
    - (IBAction)myPaste:(id)sender {
      [self.textView1 setString:…];
      [self.textView2 setString:…];
    }
    @end

    @implemenation MyAppDelegate
    - (IBAction)myPaste:(id)sender {
      [NSApp sendAction:@selector(paste:) to:nil from:sender];
    }
    @end

    --Kyle Sluder
  • On 16/06/2012, at 4:06 AM, Kyle Sluder wrote:

    > Your best bet is probably to retarget the Paste menu item to use a different selector that is picked up by your window controller.

    Thanks Kyle,

    Unfortunately the standard paste: selector is used extensively elsewhere in my app, so this simple solution would not be so simple. This is an otherwise very self-contained modal dialog that doesn't have much to do.

    I solved it as follows:

    My window controller, which is the window's delegate, implements -windowWillReturnFieldEditor:forObject:. I return a subclass of NSTextView which overrides -paste: and adds a property, -pasteDelegate: which I set to be the window controller. (I believe the FE's nextResponder is usually also the windowController, but I wasn't entirely sure I could rely on that, so I just added an extra property to hook it up). Then I just punt -paste to the -pasteDelegate (and also -validateMenuItem for that action).

    Works great. In conjunction with some text editing delegate methods I have excellent control over the text fields and the subclassing was absolutely minimal.

    --Graham
  • On Jun 15, 2012, at 4:23 PM, Graham Cox <graham.cox...> wrote:

    >
    > On 16/06/2012, at 4:06 AM, Kyle Sluder wrote:
    >
    >> Your best bet is probably to retarget the Paste menu item to use a different selector that is picked up by your window controller.
    >
    > Thanks Kyle,
    >
    > Unfortunately the standard paste: selector is used extensively elsewhere in my app, so this simple solution would not be so simple. This is an otherwise very self-contained modal dialog that doesn't have much to do.

    The good thing about this solution is that it does fall back to sending -paste:. But you are right; it does seem a bit heavy-handed for your localized need.

    >
    > I solved it as follows:
    >
    >
    > My window controller, which is the window's delegate, implements -windowWillReturnFieldEditor:forObject:. I return a subclass of NSTextView which overrides -paste: and adds a property, -pasteDelegate: which I set to be the window controller. (I believe the FE's nextResponder is usually also the windowController, but I wasn't entirely sure I could rely on that, so I just added an extra property to hook it up). Then I just punt -paste to the -pasteDelegate (and also -validateMenuItem for that action).

    Cool. In order to avoid a retain cycle or a dangling pointer, instead of using a pasteDelegate (since there's no clear place to nil the property out) I would probably just use [[self window] windowController].

    --Kyle Sluder
previous month june 2012 next month
MTWTFSS
        1 2 3
4 5 6 7 8 9 10
11 12 13 14 15 16 17
18 19 20 21 22 23 24
25 26 27 28 29 30  
Go to today