Question

I'm learning Objective-C by building a basic calculator app for OSX. Everything works beautifully, except I need to allow pressing of certain keys on the keyboard to do the same thing as if you clicked the buttons on the interface.

Everything I read says to capture these you have to have the logic in a subclass of NSResponder. My issue comes in how I "connect" that file. Creating a new .h and .m file that subclasses NSResponder like such:

Responder.h


#import <Foundation/Foundation.h>

@interface Responder : NSResponder

   - (void)keyDown:(NSEvent *)event;

@end

Responder.m


#import "Responder.h"

@implementation Responder

- (void)keyDown:(NSEvent *)event {
    NSAlert *alert = [[NSAlert alloc] init];
    [alert addButtonWithTitle:@"OK"];
    [alert setMessageText:@"Hey"];
    [alert setInformativeText:@"You Pressed A Key!"];
    [alert setAlertStyle:NSWarningAlertStyle];
    [alert runModal];
}

@end

How does the application know to use that file? Is there somewhere in the interface for the .xib file where I drag that blue arrow and "connect" it somewhere? Am I even doing it right at all? I've been googling this for a while and everything pretty much assumes I would know how to get a NSResponder subclass into my application. I'm really missing a fundamental concept here I think. Any help is appreciated!

Was it helpful?

Solution

When people say "in a subclass of NSResponder", they don't necessarily mean that you should make a new NSResponder subclass. What they mean is this: key presses are handled by responders. Your app structure is chock full of responders! So, to intervene in the key-handling process, subclass one of those (so that you have somewhere to put the code).

The "fundamental concept" that you are missing is the responder chain:

https://developer.apple.com/library/mac/#documentation/Cocoa/Conceptual/EventOverview/EventArchitecture/EventArchitecture.html

(Scroll down to the heading "Responder Chain".)

A frequent place to put this sort of code is the window controller. NSWindowController is an NSResponder subclass. It's high up in the responder chain, and you've probably already got a class for it.

Another option is to use a view. NSView is an NSResponder subclass, and your window is full of views. It wouldn't be surprising to put an otherwise inert NSView in back of everything in the window, just to function as a backstop NSResponder to catch events that come up the chain.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top