Search code examples
objective-csearchnssearchfield

NSSearchField with menu not being updated


I haev a Document Based Application, and In the document view, I have a NSSearchField. In the search field, I have enabled the menu, which I get to show up, and I have associated actions with the menu item. One of the menu items is called "Match Case". I want to be able to put (and remove) a check next this menu item. When I attempt to do so, the menu does not show the check.

-(IBAction)searchMenuMatchCase:(id)sender {
    NSMenuItem *smi = [searchMenu itemWithTitle:@"Match Case"];
    if (searchCaseSensitive) {
        searchCaseSensitive = false;
        [[searchMenu itemWithTitle:@"Match Case"] setState:NSOffState];
    } else {
        searchCaseSensitive = true;
        [[searchMenu itemWithTitle:@"Match Case"] setState:NSOnState];
    }
    [searchMenu update];
    NSLog(@"SM State %ld",[smi state]);
}

The code gets executed, and I get a log message showing the state going from 0 to 1 to 0 to 1. But there is never a check next to the menu item. When I look at the menu item object while debugging, I do see the "state" value set to 0 and 1 before I toggle it.

Any suggestions as to what I am missing?


Solution

  • To get around this issue, I had to use the NSMenuDelegate and use the method validateMenuItem. This way the validateMenuItem method was called before the menu was drawn, and I could make sure the state was set correctly before the menu was drawn. I believe what was happening was that the menu item I was getting in the original code was not the actual menu that was being drawn, but just a template.

    /**
     This is called when the user selectes the "Match Case" menu item found in the Search field
     */
    -(IBAction)searchMenuMatchCase:(id)sender {
        if (searchCaseSensitive) {
            searchCaseSensitive = false;
        } else {
            searchCaseSensitive = true;
        }
    }
    
    /**
     This is called Each time a menu is shown.
     */
    -(BOOL) validateMenuItem:(NSMenuItem *)menuItem {
    
        if ([[menuItem title] compare:@"Match Case"] == 0) {
            if (searchCaseSensitive) {
                [menuItem setState:NSOnState];
            } else {
                [menuItem setState:NSOffState];
            }
        }
        return YES;
    }