NSControlTextDidChangeNotification fires only once upon setting delegate

  • Hello list.

    I'm trying to implement a Safari-style address field with completion.
    I'm using an ImageAndTextCell in an NSMatrix, and trying to leverage
    the built-in completion by doing the following in my controller code:

    * Observe NSControlTextDidChangeNotification notifications from the
    NSMatrix.
    * When the NSControlTextDidChangeNotification arrives, get the field
    editor for the ImageAndTextCell, and set the field editor's delegate
    to my controller, so that I get
    textView:completions:forPartialWordRange:indexOfSelectedItem:
    delegate calls.
    * In textView:completions:forPartialWordRange:indexOfSelectedItem:, I
    fetch the matching items and return them.

    This works as expected, but only the first time, that is, when I type
    the first character in the field. It fills in the field and selects
    the part following the keyboard input, and displays the pull-down
    list with that item selected. However, I do not get
    NSControlTextDidChangeNotification for subsequent key presses, hence
    no completion and no pull-down.

    If I comment out the body of the NSControlTextDidChangeNotification
    handler and replace it with an NSLog, I see it is called as expected
    for all characters. Setting the delegate seems to be enough to cause
    the problem.

    Am I doing something wrong in my delegate that keeps subsequent
    notifications from firing? I have tried google searches and read the
    NSTextView class documentation, and I'm stuck.

    Is this the wrong approach? Any suggestions are welcome.

    Thank you.
  • On 9/28/07, <ncdev05...> <ncdev05...> wrote:
    > Am I doing something wrong in my delegate that keeps subsequent
    > notifications from firing? I have tried google searches and read the
    > NSTextView class documentation, and I'm stuck.
    >
    > Is this the wrong approach? Any suggestions are welcome.

    You're thinking about this too hard. Here's silly code that works,
    just set MyController as the delegate of NSMatrix:

    #import <Cocoa/Cocoa.h>

    @interface MyController : NSObject
    {
    }

    - (void) controlTextDidChange:(NSNotification*)aNotification;

    - (NSArray*) control:(NSControl*)control
      textView:(NSTextView*)textView
            completions:(NSArray*)words
    forPartialWordRange:(NSRange)charRange
    indexOfSelectedItem:(int*)index;

    @end

    @implementation MyController

    /* delegates automatically get this message, you don't need
    * to register for it seperately */
    - (void) controlTextDidChange:(NSNotification *)aNotification
    {
    [[[aNotification userInfo] objectForKey:@"NSFieldEditor"] complete:nil];
    }

    /* The NSMatrix is a delegate of the field editor, and it passes this message
    * on to its delegate. So when you changed the delegate of the field editor,
    * you unwittingly broke what NSMatrix expects to happen. Which is why things
    * stopped working */
    - (NSArray*) control:(NSControl*)control
      textView:(NSTextView*)textView
            completions:(NSArray*)words
    forPartialWordRange:(NSRange)charRange
    indexOfSelectedItem:(int*)index
    {
    NSMutableArray *rv = [NSMutableArray array];
    NSString *text = [textView string];

    [rv addObject:[text stringByAppendingString:text]];
    [rv addObject:[text stringByAppendingString:
      [text stringByAppendingString:text]]];
    [rv addObject:[text stringByAppendingString:
      [text stringByAppendingString:
      [text stringByAppendingString:text]]]];

    *index = -1;

    return rv;
    }

    @end
previous month september 2007 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