2010-04-14 14 views
12

Ho cercato dappertutto un semplice esempio di come attivare un'azione (o un pulsante) quando si preme il tasto Invio nel campo di testo.NSTextField enter per attivare l'azione

Devo sottoclasse il campo di testo? Dovrei impostare un delegato per chiamare l'azione di cui ho bisogno? C'è un modo per catturare l'evento nella mia classe di controller finestra principale?

Se potessi anche indicarmi la direzione giusta sarebbe fantastico. Grazie.

risposta

9

Per ottenere un'azione dopo aver premuto invio, basta scrivere un IBAction nel controller della finestra e connettersi al campo di testo. Se vuoi più come il tuo metodo dovrebbe essere chiamato quando ti concentri sul campo di testo e lasci il campo di testo devi impostare delegato (See here).

+1

Ciao, Grazie, ma come faccio a filtrare per il tasto Invio perché quando si mettono a fuoco o sfocatura dal campo di testo viene attivata anche l'azione. THanks – Chris

+0

Per ricevere una notifica quando la modifica è completa (immettere chiave o tasto tab viene colpito) viene chiamato il metodo controlTextDidEndEditing della classe delegato, in cui è possibile attivare l'azione. Se vuoi che la tua azione venga attivata solo per la chiave di invio, devi scrivere un formattatore personalizzato o una classe NSTextfield personalizzata. – Raviprakash

+1

THANK Gudda. In realtà ho appena scoperto che puoi inviare l'azione solo su invio come descritto qui: http://mojomonkeycoding.com/2009/11/14/calling-an-action-when-hitting-return-in-an-nstextfield /. Quindi per fortuna non c'è bisogno di sottoclasse. – Chris

2

Basta collegare un IBAction della classe controller con un campo di testo. L'azione dovrebbe essere chiamata con il tasto invio o lasciare il campo di testo con Tab o Mouse.

22

Il sito a cui si fa riferimento nei commenti alla risposta accettata ... è ora "SUSPENDED" dal webhost e la cache di Google non ha lo screenshot che contiene il passaggio chiave.

Quindi, ecco una soluzione alternativa ho scoperto che:

  1. funziona perfettamente
  2. non richiede sottoclasse

Per alcuni tasti (ENTER, Elimina, Backspace, ecc), Apple fa NON richiamare i normali metodi controlTextDidEndEditing: etc. Invece, Apple seleziona i singoli selettori per ogni chiave magica, ma c'è un metodo che puoi usare per intercettarlo.

documentazione ufficiale

di Apple qui:

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

... ma nel caso in cui si annulla/viene spostato, aggiungere questo metodo nel vostro delegato:

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

Nel mio caso, ho voluto per sovrascrivere anche il tasto backspace - eseguendo l'app con questo metodo, ho ricevuto un output che diceva che il selettore era "deleteBackward:", quindi ho aggiunto un'altra istruzione if lì per reagire.

+0

FYI, se vuoi catturare la chiave di invio quando il pop-up di completamento di NSTextView è aperto, questo metodo non funzionerà perché doCommandBySelector: non viene richiamato. Invece, puoi solo guardare per '[[NSApp currentEvent] .charactersIgnoringModifiers isEqualToString: @" \ r "]' in 'controlTextDidChange:' – lhunath

+0

Its Awesome man, funziona come CHARM –

1

Per i curiosi, ecco come implementare -controlTextDidEndEditing:(NSNotification)obj (se non si cura di rispondere a solo il tasto Invio)

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

Ha funzionato come un incantesimo per me.

1

La cosa migliore da fare sarebbe utilizzare control + drag per l'azione che hai già creato, quindi premere return attiverà anche l'azione.

+3

Sì. Inoltre, puoi (se il tuo Interface Builder non è ** molto ** vecchio), seleziona il tuo NSTextField, apri l'ispettore Attributes e cambia l'azione in "Send on Enter Only" invece di "Send on End Editing"; ciò semplifica il corretto funzionamento di NSTextField, ad esempio un campo URL per un browser Web. –