Получение функциональной клавиши нажатием на NSSearchField без подклассов
У меня есть простое приложение, которое имеет NSSearchField
и я хочу знать, нажимает ли пользователь, например, клавишу со стрелкой. Я не хочу создавать подклассы, потому что я хочу изменить значения IBOutlets в моем приложении, и я не могу сделать это в подклассе.
РЕДАКТИРОВАТЬ
keyUp:
метод, который я переопределить в моем NSSearchField
подкласс это:
-(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
}
}
3 ответа
Назначьте ваш контроллер в качестве делегата вашего поля поиска и реализуйте метод:
- (BOOL)control:(NSControl *)control textView:(NSTextView *)textView doCommandBySelector:(SEL)command
После этого вы сможете получать простые селекторы NSResponder, такие как moveDown:, moveUp:, moveLeft:, moveRight:, которые соответствуют клавишам со стрелками.
NSSearchField наследуется от NSControl, который имеет метод делегата, который вы ищете.
- (void)controlTextDidChange:(NSNotification *)aNotification
Установите NSSearchField в качестве вашего делегата и реализуйте этот метод. Возможно, вы захотите запустить проверку, чтобы убедиться, что ваш NSSearchField начал редактирование. Может быть, вы могли бы использовать FirstResponder. Что-то вроде:
- (void)controlTextDidChange:(NSNotification *)aNotification {
If (mySearchField.isFirstResponder) {
//throwdown
}
}
Там нет никакого способа получить NSEvent
s, которые уже были переданы представлению, чей код у вас нет. Если вы хотите изменить поведение обработки представления или элемента управления, вы должны создать подкласс. Возможно, вам удастся вставить другой объект перед полем поиска в цепочке респондента, получить событие, сделать все, что вы хотите, а затем действовать так, как будто вы его не обработали, и передать его в поле... просто дикая мысль от макушки моей головы.
ОБНОВЛЕНИЕ в ответ на ваш keyUp:
код:
Хорошо, проблема становится понятной. Когда вы создаете этот новый customer
* объект в коде, вы также должны подключить его соединения в коде. Они не связаны для вас. Вы на самом деле не используете IBOutlets
для этого просто обычные старые ивары. IBOutlets
только там, чтобы вы могли подключать объекты в графическом интерфейсе Interface Builder. Я не знаю точно, что вы пытаетесь сделать в searcht:
, но только в качестве примера, если вы хотите изменить содержимое текстового поля:
- (void)searcht:(NSString *)theString {
// Do some stuff with the string
[myTextField setStringValue:someResultString];
}
Где customer.h выглядит примерно так:
@interface customer : NSObject {
IBOutlet NSTextField * myTextField;
}
Это ничего не даст, в том числе не даст предупреждения, потому что myTextField
является nil
, Вы можете вызывать методы на nil
весь день и ничего не случится. Что вам нужно сделать, это дать customer
объект указатель на текстовое поле; это не должно быть IBOutlet
, Вы могли бы сделать это в init...
метод, или просто установив его напрямую (обратите внимание, что это означает, что поле поиска должно иметь соединение с текстовым полем, чтобы передать его в Customer
, что может быть или не быть желательным):
@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
* Кроме того, условно имена классов в Obj-C начинаются с заглавных букв: "Клиент", а не "Клиент".