Question

I have a simple application which has an NSSearchField and I want to know if the user presses, for example, an arrow key. I don't want to subclass, because I want to modify the values of the IBOutlets in my aplication, and I can't do that in a subclass.

EDIT

The keyUp: method that I override in my NSSearchField subclass is:

-(void)keyUp:(NSEvent*)event
{
    if ([event keyCode]==36){
    customers* c= [[customers alloc] init];//customers is the class where i have my IBOulets and my methods
    [[self window] selectKeyViewFollowingView:self];// change the first responder
    [c searcht:[self stringValue]];//here i want to call a method to make a query and change the stringValues of some IBOulets
    }
}
Was it helpful?

Solution

Assign your controller as the delegate of your searchfield and implement the method:

- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command

You should then be able to receive simple NSResponder selectors such as moveDown:, moveUp:, moveLeft:, moveRight: which correspond to the arrow keys.

OTHER TIPS

NSSearchField inherits from NSControl which has the delegate method you are looking for.

- (void)controlTextDidChange:(NSNotification *)aNotification

Set the NSSearchField as your delegate and implement this method. Might want to run a check to make sure it's your NSSearchField that's started editing. Maybe you could use FirstResponder. Something like:

- (void)controlTextDidChange:(NSNotification *)aNotification {
    If (mySearchField.isFirstResponder) {
        //throwdown
    }
}

http://developer.apple.com/library/mac/#documentation/cocoa/reference/ApplicationKit/Classes/NSControl_Class/Reference/Reference.html#//apple_ref/occ/cl/NSControl

There's no way to get the NSEvents that have already been handed to a view whose code you don't have. If you want to change the key-handling behavior of a view or control, you have to subclass. You might be able to insert another object before the search field in the responder chain, get the event, do whatever you want, and then act like you didn't handle it and pass it on to the field...just a wild thought from the top of my head.

UPDATE in reply to your keyUp: code:

Okay, the problem is becoming clear. When you create that new customer* object in code, you also have to hook up its connections in code. They're not connected for you. You don't actually use IBOutlets for this, just regular old ivars. IBOutlets are only there so that you can connect objects in the graphical interface of Interface Builder. I don't know exactly what you're trying to do in searcht:, but just as an example, if you wanted to change the contents of a text field:

- (void)searcht:(NSString *)theString {

    // Do some stuff with the string

    [myTextField setStringValue:someResultString];

}

Where customer.h looks something like:

@interface customer : NSObject {
    IBOutlet NSTextField * myTextField;
}

This will do nothing, including give no warning, because myTextField is nil. You can call methods on nil all day long and nothing will happen. What you need to do is give the customer object a pointer to the text field; this should not be an IBOutlet. You could do this in an init... method, or just by setting it directly (note that this means that the search field will have to have a connection to the text field in order to pass it on to the Customer, which may or may not be desirable):

@interface Customer : NSObject {
    NSTextField * myTextField;
}

@property NSTextField * myTextField;    // Note: does not need to be retained.
@end

#import "Customer.h"

@implementation Customer

@synthesize myTextField;

- (id)initUsingTextField:(NSTextField *)tf {

    if( !(self = [super init]) ) {
        return nil;
    }

    myTextField = tf;

    return self;
}

@end

*As an aside, conventionally class names in Obj-C start with uppercase letters: "Customer", not "customer".

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