Search code examples
objective-cmacosinterface-buildernsbutton

key Equiv. for nsbutton is not working properly for multiple nsbuttons


I have two nsbuttons in my interface builder.For all of these three nsbuttons I have set Key Equilant to "Return" key.And also I set nextkey view to all of these buttons.

I have 3 different actions for all of these three buttons and connections has made properly. If I use mouse click appropriate actions are getting executed.

After running the Application,initially my first button has focus,presses return key, 1st button's action is executed.Next I pressed tab key,focussed has changed to 2nd button,pressed return key but 1st button's action is executed.Again I pressed tab key,focussed has changed to 3rd button,pressed return key still 1st button's action is executed.

What I am missing here.Why the appropiate action is not happenning on pressing Return key over nsbutton even focus is highlighted.


Solution

  • It sounds like you're using keyboard navigation to switch between buttons and activate the selected one. In that case, the Return key would normally correspond to pressing the selected button. However, since you've assigned Return as a shortcut for one or more of the buttons, the responder chain searches for and finds a button with a matching key equivalent, so that button's message is sent instead.

    Try clearing the key equivalent for all three of your buttons. I think that'll give the behavior you're looking for.

    If you're not using keyboard navigation, it's not clear why the tab button has any effect. Nevertheless, if you're trying to do something like make the default button cycle from one button to the next, you'll need to change the keyboard equivalent each time a button is pressed. I wouldn't recommend that generally -- I don't think users would like to have the default button change from one moment to the next. If you must though, here's some code:

    - (IBAction)nextButton:(NSButton*)sender
    {
        int tag = [sender tag];
        NSView *superview = [sender superview];
        if ([sender.keyEquivalent isEqualToString:@"\r"]) {
            NSButton *nextButton = [superview viewWithTag:(tag % 3) + 1];
            nextButton.keyEquivalent = @"\r";
            sender.keyEquivalent = @"";
        }
    }
    

    This assumes that you've got three buttons, and each is configured with the nextButton: method as its action. Also, the buttons have tags 1, 2, and 3 respectively. The idea here is that when the default button (i.e. the one with the return key as its equivalent) is selected, it sets the next button's key equivalent to Return and sets its own equivalent to nothing.

    You can obviously change the way the code works -- you may want each button to call a different action, for example. In that case, just have each action call a common method that does the same job as the code above.

    The lesson here is that if you set the same key equivalent for several buttons, the first one to be found will be "pressed". If you want the key equivalent to change, you need to change the equivalent set for your various buttons.