2010-04-14 1 views
12

Я искал все для простого примера того, как заставить действие (или кнопку) запускаться при нажатии клавиши ввода в текстовом поле.NSTextField вводит действие триггера

Должен ли я подклассировать текстовое поле? Должен ли я установить делегата для вызова необходимого мне действия? Есть ли способ поймать событие в моем классе контроллера главного окна?

Если бы вы могли просто указать мне в правильном направлении, это было бы здорово. Благодарю.

ответ

9

Чтобы получить действие после того, как вы нажмете enter, просто напишите IBAction в своем оконном контроллере и подключитесь к текстовому полю. Если вы хотите больше, как ваш метод следует вызывать, когда вы фокусируетесь на текстовом поле и оставляете текстовое поле, вам нужно установить делегат (See here).

+1

Привет, Спасибо, что я сделал это, но как отфильтровать ключ ввода, потому что, когда они фокусируются или размываются из текстового поля, действие также запускается. THanks – Chris

+0

Чтобы получить уведомление, когда редактирование завершено (либо введите ключ, либо нажата клавиша табуляции), вызывается метод управления делегатом classTextDidEndEditing, там вы можете вызвать действие. Если вы хотите, чтобы действие было инициировано только для ввода ключа, вам нужно либо написать собственный форматировщик, либо настроить класс NSTextfield. – Raviprakash

+1

Черты Гудда. Я только что узнал, что вы можете отправить это действие только для ввода, как описано здесь: http://mojomonkeycoding.com/2009/11/14/calling-an-action-when-hitting-return-in-an-nstextfield /. К счастью, нет необходимости в подклассе. – Chris

2

Просто подключите IBAction вашего класса контроллера с текстовым полем. Действие должно быть вызвано, если вы нажмете Enter или оставьте текстовое поле с помощью Tab или Mouse.

22

Сайт, на который ссылаются в комментариях к принятому ответу ... теперь «ПОДОЗРЕВАЕМ» на веб-хосте, а в кеше Google нет скриншота, содержащего ключевой шаг.

Итак, вот альтернативное решение, которое я нашел, что:

  1. работает отлично
  2. не требует подклассов

Для некоторых клавиш (Enter, Delete, Backspace и т.д.), Apple делает НЕ вызывать обычные методы controlTextDidEndEditing: etc. Вместо этого Apple делает отдельные селекторы для каждого волшебного ключа, но есть метод, который вы можете использовать для его перехвата.

официальные документы

компании Apple здесь:

https://developer.apple.com/library/mac/documentation/TextFonts/Conceptual/CocoaTextArchitecture/TextEditing/TextEditing.html#//apple_ref/doc/uid/TP40009459-CH3-SW31

... но в случае, когда исчезает/получает перемещается, добавьте этот метод в ваш делегат:

- (BOOL)control:(NSControl *)control textView:(NSTextView *)fieldEditor doCommandBySelector:(SEL)commandSelector 
{   
    BOOL retval = NO; 

    if (commandSelector == @selector(insertNewline:)) { 

     retval = YES; // causes Apple to NOT fire the default enter action 

     // Do your special handling of the "enter" key here 

    } 

    NSLog(@"Selector = %@", NSStringFromSelector(commandSelector)); 

    return retval; 
} 

В моем случае, я хотел для переопределения клавиши backspace тоже - запуск приложения с помощью этого метода, я получил вывод, в котором говорилось, что селектор был «deleteBackward:», поэтому я добавил еще один if-statement, чтобы реагировать на это.

+0

FYI, если вы хотите поймать ключ ввода при открытии всплывающего окна NSTextView, этот метод не будет работать, потому что doCommandBySelector: не будет вызван. Вместо этого вы можете просто смотреть на '[[NSApp currentEvent] .charactersIgnoringModifiers isEqualToString: @" \ r "]' in 'controlTextDidChange:' – lhunath

+0

Уверенный человек, работающий как CHARM –

1

Для любопытных, вот как реализовать -controlTextDidEndEditing:(NSNotification)obj (если вы не заботитесь о реагировании на просто ввести ключ)

AppDelegate.h:

// Conform to the protocol to avoid compiler warnings 
@interface myClass : NSObject <NSTextFieldDelegate> 

// Link up to the interface elements you want to trigger 
@property (weak) IBOutlet NSTextField *myTextField; 
@property (weak) IBOutlet NSButton *myButton; 

// Create an action linked to myButton 
- (IBAction)myButtonPressed:(id)sender; 

// Advertise that you implement the method 
- (void)controlTextDidEndEditing:(NSNotification *)obj; 

AppDelegate.m:

@synthesize myTextField = _myTextField; 
@synthesize myButton = _myButton; 

// Make yourself the delegate 
- (void)applicationDidFinishLoading:(NSNotification *)aMessage { 
    _myTextField.delegate = self; 
} 

// NSTextField objects send an NSNotification to a delegate if 
// it implements this method: 

- (void)controlTextDidEndEditing:(NSNotification *)obj { 
    if ([[obj object] isEqual:_textField]) { 
     [self myButtonPressed:nil]; // nil = sender 
    } 
} 

Работал как очарование для меня.

1

Лучшее, что нужно сделать, - использовать control + drag для действия, которое вы уже создали, поэтому нажатие return также вызовет действие.

+3

Да. Кроме того, вы можете (если ваш построитель интерфейса не очень старый), выберите свой NSTextField, откройте Инспектор атрибутов и измените действие на «Отправить только на вход» вместо «Редактирование отправки на конец»; это облегчает правильное поведение NSTextField, например, для URL-поля для веб-браузера. – 2014-11-13 05:45:46