Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

KeyEvents in Cocoa and XCode

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!

like image 854
Jeremy Harris Avatar asked Jan 01 '26 08:01

Jeremy Harris


1 Answers

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.

like image 57
matt Avatar answered Jan 04 '26 03:01

matt



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!