1

I have a cell-based NSOutlineView which displays NSTextFieldCell objects.

I'd like to respond to keydown or keyup events so as to make the text contained in the NSTextFieldCell bold when the text contains certain preset keywords. What is the most elegant way to achieve this - should I:

  • Subclass NSOutlineView and override the keydown method
  • Subclass NSTextFieldCell
  • Utilize a delegate of some kind
  • Utilize some other approach

Thanks very much in advance to all for any info!

Thomas Tempelmann
  • 11,045
  • 8
  • 74
  • 149
VikR
  • 4,818
  • 8
  • 51
  • 96
  • Uh, maybe I should have rephrased the question to limit it to the special request of the original author instead of broadening it with a bounty. Too late now. – Thomas Tempelmann Mar 20 '17 at 12:44

2 Answers2

0

Found it.

In awakeFromNib:

[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(actionToTakeOnKeyPress:)  name:NSControlTextDidChangeNotification object:theNSOutlineViewThatContainsTheNSTextFieldCell]; 

Then add a method like this:

- (void) actionToTakeOnKeyPress: (id) sender
{
    //will be called whenever contents of NSTextFieldCell change
}
VikR
  • 4,818
  • 8
  • 51
  • 96
  • I have the same question, but your answer does not fit because that notification is called AFTER the typed key has already been handled by the text field. I need to intercept the key press before, and optionally discard it so that it does not end up in the text field. For that, according to docs, keyDown has to be overwritten, which is something I can't figure out for an NSTextFieldCell, though. – Thomas Tempelmann Mar 20 '17 at 12:21
0

To intercept key presses in a way that they can still be filtered out, various NSResponder messages may be overwritten, such as keyDown: or interpretKeyEvents:.

To be able to do that, a subclass of a NSTextView needs to be used as the field editor. For that, one subclasses NSTextFieldCell and overrides fieldEditorForView:, returning the subclass (see Custom field editor for NSTextFieldCell in an NSTableView).

Here's the relevant code excerpts:

In a subclassed NSTextFieldCell (which then has to be assigned in Interface Builder for the editable column, or returned by the NSTableViewDelegate's dataCellForTableColumn message):

- (NSTextView *)fieldEditorForView:(NSView *)aControlView
{
    if (!self.myFieldEditor) {
        self.myFieldEditor = [[MyTextView alloc] init];
        self.myFieldEditor.fieldEditor = YES;
    }
    return self.myFieldEditor;    
}

It also requires the declaration of a property in the @interface section:

@property (strong) MyTextView *myFieldEditor;

And then in MyTextView, which is a subclass of NSTextView:

-(void)keyDown:(NSEvent *)theEvent
{
    NSLog(@"MyTextView keyDown: %@", theEvent.characters);
    static bool b = true;
    if (b) { // this silly example only lets every other keypress through.
        [super keyDown:theEvent];
    }
    b = !b;
}
Community
  • 1
  • 1
Thomas Tempelmann
  • 11,045
  • 8
  • 74
  • 149
  • Again, sorry for opening a bounty but then posting my own solution. This all took me over 4 hours to figure out, and in the middle of it I thought I could not find a solution so I started the bounty too early. And I can't take it back now. – Thomas Tempelmann Mar 20 '17 at 14:13