2010-06-24 3 views
9

Provare a cambiare il colore di sfondo del testo selezionato per un NSTextField (abbiamo un'interfaccia utente scura, e lo sfondo del testo selezionato è quasi lo stesso del testo stesso), ma solo NSTextView sembra permetterci di cambiarlo.Fingendo un NSTextField usando un NSTextView per ottenere una bella colorazione?

Quindi stiamo provando a simulare un NSTextField utilizzando un NSTextView, ma non è possibile ottenere lo scorrimento del testo per funzionare allo stesso modo.

Il più vicino che otteniamo è con questo codice:

NSTextView *tf = [ [ NSTextView alloc ] initWithFrame: NSMakeRect(30.0, 20.0, 80.0, 22.0) ]; 

// Dark UI 
[tf setTextColor:[NSColor whiteColor]]; 
[tf setBackgroundColor:[NSColor darkGrayColor]]; 

// Fixed size 
[tf setVerticallyResizable:FALSE]; 
[tf setHorizontallyResizable:FALSE]; 

[tf setAlignment:NSRightTextAlignment]; // Make it right-aligned (yup, we need this too) 

[[tf textContainer] setContainerSize:NSMakeSize(2000, 20)]; // Try to Avoid line wrapping with this ugly hack 
[tf setFieldEditor:TRUE]; // Make Return key accept the textfield 

// Set text properties 
NSMutableDictionary *dict = [[[tf selectedTextAttributes] mutableCopy ] autorelease]; 
[dict setObject:[NSColor orangeColor] forKey:NSBackgroundColorAttributeName]; 
[tf setSelectedTextAttributes:dict]; 

Questo funziona quasi bene, tranne che se il testo è più lungo del campo di testo, non è possibile scorrere ad esso in alcun modo.

Qualche idea su come realizzare questo?

Grazie in anticipo

Edit: soluzione suggerita seguito da Joshua Nozzi

Grazie a Joshua, questa è una grande soluzione a quello che stavo cercando:

@interface ColoredTextField : NSTextField 
- (BOOL)becomeFirstResponder; 
@end 

@implementation ColoredTextField 
- (BOOL)becomeFirstResponder 
{ 
    if (![super becomeFirstResponder]) 
     return NO; 

    NSDictionary * attributes = [NSDictionary dictionaryWithObjectsAndKeys : 
        [NSColor orangeColor], NSBackgroundColorAttributeName, nil]; 

    NSTextView * fieldEditor = (NSTextView *)[[self window] fieldEditor:YES forObject:self]; 
    [fieldEditor setSelectedTextAttributes:attributes]; 
    return YES; 
} 
@end 

Invece di fingere con un NSTextView, è solo un NSTextField che cambia il colore del testo selezionato quando diventa il primo risponditore.

Modifica: Il codice sopra riportato torna al colore di selezione predefinito una volta premuto Invio nel campo di testo. Ecco un modo per evitarlo.

@interface ColoredTextField : NSTextField 
- (BOOL)becomeFirstResponder; 
- (void)textDidEndEditing:(NSNotification *)notification; 

- (void)setSelectedColor; 
@end 

@implementation ColoredTextField 
- (BOOL)becomeFirstResponder 
{ 
    if (![super becomeFirstResponder]) 
     return NO; 
    [self setSelectedColor]; 
    return YES; 
} 

- (void)textDidEndEditing:(NSNotification *)notification 
{ 
    [super textDidEndEditing:notification]; 
    [self setSelectedColor]; 
} 

- (void) setSelectedColor 
{ 
    NSDictionary * attributes = [NSDictionary dictionaryWithObjectsAndKeys : 
           [NSColor orangeColor], NSBackgroundColorAttributeName, nil]; 

    NSTextView * fieldEditor = (NSTextView *)[[self window] fieldEditor:YES forObject:self]; 
    [fieldEditor setSelectedTextAttributes:attributes]; 
} 
@end 

risposta

6

Perché non solo impostare le proprietà del campo di testo del field editor direttamente quando il campo becomes first responder?

In un campo di testo tipico, la selezione è visibile solo quando il campo è primo soccorritore, quindi se chiedete editor di campo del campo di testo, quindi impostare attribuisce la sua testo selezionato, si otterrebbe lo stesso effetto, wouldn sei tu?

NSDictionary * attributes = [NSDictionary dictionaryWithObjectsAndKeys: 
    [NSColor orangeColor], NSBackgroundColorAttributeName, nil]; 
NSTextView * fieldEditor = (NSTextView *)[[self window] fieldEditor:YES 
    forObject:textField]; 
[fieldEditor setSelectedTextAttributes:attributes]; 

Nota: Come discusso nei commenti qui sotto, la documentazione è corretta quando dice l'editor di campo è un esempio di NSTextView, ma il - [NSWindow fieldEditor: forObject:] metodo sostiene di restituire un NSText (Superclasse immediata di NSTextView). Se si pianifica di inviare i metodi NSTextView dell'editor di campo, è necessario eseguire il cast come NSTextView per disattivare gli avvisi del compilatore. Il casting non romperà nulla nel tuo codice, nel caso in cui il prototipo del metodo venga corretto in futuro, quindi può essere lasciato al sicuro.

+0

Dai un'occhiata a questa risposta ad un'altra domanda. Mostra come manipolare l'editor di campi per un NSTokenField (che è una sottoclasse di NSTextField, quindi funziona esattamente allo stesso modo). http://stackoverflow.com/questions/2995205/prevent-selecting-all-tokens-in-nstokenfield –

+0

L'editor di campi del campo di testo è un oggetto NSText e quella classe non ha neanche il metodo setSelectedTextAttributes. A meno che mi manchi qualcosa, non sembra che possa essere fatto in questo modo. – hasvn

+0

@hasvn: Questo confonde ... il prototipo di '- [NSWindow fieldEditor: forObject:]' dice restituisce 'NSText *', ma la documentazione dice che l'editor di campi è un oggetto NSTextView. – JWWalker