Получение функциональной клавиши нажатием на NSSearchField без подклассов - PullRequest
3 голосов
/ 29 апреля 2011

У меня есть простое приложение с NSSearchField, и я хочу знать, нажимает ли пользователь, например, клавишу со стрелкой. Я не хочу создавать подкласс, потому что я хочу изменить значения IBOutlets в своем приложении, и я не могу сделать это в подклассе.

EDIT

Метод 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 ]

11 голосов
/ 30 апреля 2011

Назначьте ваш контроллер в качестве делегата вашего поля поиска и реализуйте метод:

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

После этого вы сможете получать простые селекторы NSResponder, такие как moveDown :, moveUp :, moveLeft :, moveRight: whichсоответствуют клавишам со стрелками.

2 голосов
/ 29 апреля 2011

NSSearchField наследуется от NSControl, который имеет метод делегата, который вы ищете.

- (void)controlTextDidChange:(NSNotification *)aNotification

Установите NSSearchField в качестве вашего делегата и реализуйте этот метод.Возможно, вы захотите запустить проверку, чтобы убедиться, что ваш NSSearchField начал редактирование.Может быть, вы могли бы использовать FirstResponder.Что-то вроде:

- (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

1 голос
/ 29 апреля 2011

Нет способа получить NSEvent, которые уже были переданы представлению, чей код у вас нет.Если вы хотите изменить поведение обработки представления или элемента управления, вам нужно создать подкласс.Возможно, вы сможете вставить другой объект перед полем поиска в цепочке респондента, получить событие, сделать все, что захотите, а затем действовать так, как будто вы его не обработали, и передать его в поле.... просто дикая мысль из головы.

ОБНОВЛЕНИЕ в ответ на ваш 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 начинаются с заглавных букв: «Customer», а не «customer».

...