I have a simple application which has an 开发者_如何学PythonNSSearchField
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
}
}
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.
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 NSEvent
s 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".
精彩评论