Udawanie NSTextField za pomocą NSTextView, aby uzyskać ładne kolorowanie?

Próbuje zmienić kolor tła zaznaczonego tekstu dla NSTextField (mamy ciemny interfejs użytkownika, a tło zaznaczonego tekstu jest prawie takie samo jak sam tekst), ale tylko NSTextView wydaje się, że pozwala nam to zmienić.

Próbujemy sfałszować NSTextField używając NSTextView, ale nie możemy przewijać tekstu tak samo.

Najbliżej jest ten kod:

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];

To działa prawie W porządku, z tym, że jeśli tekst jest dłuższy niż tekst field, nie można do niego w żaden sposób przewijać.

Jakiś pomysł jak to osiągnąć?

Z góry dzięki

Edit: rozwiązanie zaproponowane poniżej przez Joshua Nozzi

Dzięki Joshui, jest to świetne rozwiązanie tego, czego szukałem:

@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

Zamiast udawania za pomocą NSTextView, jest to po prostu NSTextField, które zmienia wybrany kolor tekstu, gdy staje się pierwszym odpowiedzialnym.

Edit: powyższy kod wraca do domyślny kolor zaznaczenia po naciśnięciu klawisza Enter w polu tekstowym. Jest sposób, aby tego uniknąć.

@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
Author: Community, 2010-06-24

1 answers

Dlaczego po prostu nie ustawić właściwości edytora pola tekstowego bezpośrednio, gdy pole stanie się pierwszym odpowiedzialnym ?

W typowym polu tekstowym zaznaczenie jest widoczne tylko wtedy, gdy pole jest pierwszym odpowiedzialnym, więc jeśli poprosisz o edytor pól pola tekstowego, a następnie Ustaw jego Wybrane atrybuty tekstu, otrzymasz taki sam wpływ, prawda?

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

Uwaga: Jak wspomniano w komentarzach poniżej, dokumentacja jest poprawna, mówiąc pole edytor jest instancją NSTextView, ale metoda -[NSWindow fieldEditor:forObject:] twierdzi, że zwraca nstext (natychmiastową superklasę nstextview). Jeśli planujesz wysłać edytor pól nstextview-only methods, musisz wysłać go jako NSTextView, aby wyciszyć ostrzeżenia kompilatora. Casting nie złamie niczego w kodzie, jeśli prototyp metody zostanie poprawiony w przyszłości, więc można go bezpiecznie pozostawić na swoim miejscu.

 6
Author: Joshua Nozzi,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-06-24 18:29:43