Editable transparent text NSTextField appears with white highlight
I am trying to create an editable transparent NSTextField in a semi-transparent window:
What I noticed is that whenever the field is edited, there is a white background "matched selection" even though the item is not actually selected.
Additional observed symptoms:
- This highlight is absent if the field is set as non-editable.
- If there are multiple fields, only the first is highlighted.
- No selection if the text is not set programmatically
The following code was used to generate the field:
f = [[NSTextField alloc] initWithFrame:b2];
f.backgroundColor = [NSColor clearColor];
f.drawsBackground = YES;
f.bordered = NO;
f.bezeled = NO;
f.focusRingType = NSFocusRingTypeNone;
f.textColor = [NSColor whiteColor];
f.editable = YES;
f.selectable = YES;
f.backgroundColor = [NSColor clearColor];
f.allowsEditingTextAttributes = YES;
f.stringValue = @"Foo";
[self.contentView addSubview:f];
Additional observations (potentially a separate issue):
- When the field is not the first field on the screen, and the original text is set programmatically and removed by editing the field, a text shadow appears:
I cannot find any documentation on this. I wonder if any of you had this happen and potentially had a solution or pointer to docs that I might not have stumbled upon.
source to share
part 1: remove selection
there are two options here depending on the behavior you are looking for
option 1 - nil first responder
- TextField is not the first responder
- No selected text
- No cursor at the end of the text
Assuming you are using NSWindow, set the first responder to nil after calling makeKeyAndOrderFront
[self.window makeKeyAndOrderFront:self];
[self.window makeFirstResponder:nil];
It seems to be makeKeyAndOrderToFront:
looking for the first NSR responder in the window, ready to receive the first responder. Then this responder is called becomeFirstResponder
; leading to option 2
option 2 - override startFirstResponder
- TextField - first responder
- No selected text
- The cursor appears at the trailing edge of the text
Subclass NSTextfield and override its getFirstResponder method
@implementation BPTextField
- (BOOL)becomeFirstResponder {
BOOL isResponder = [super becomeFirstResponder];
//Get Field editor, set selected range
NSText* fieldEditor = [[self window] fieldEditor:YES forObject:self];
[fieldEditor setSelectedRange:NSMakeRange(fieldEditor.string.length ,0)];
return isResponder;
}
@end
I prefer this option in terms of usability
part 2: shadow removal
option 1 - add solid background color
I don't understand;) why this is, but if you add a solid background color, the text will update.
option 2 - override textDidChange
override textDidChange:notification
to textbox
@implementation BPTextField
- (void)textDidChange:(NSNotification *)notification {
[super textDidChange:notification];
[self setNeedsDisplay:YES];
}
@end
Final Notes
You will notice that the text looks bad or harsh. Adding a background color to a text box or supervisor level will fix this.
source to share