NSTextField - 黑色背景上的白色文本,但黑色光标

时间:2022-10-13 21:18:26

I've setup an NSTextField with text color as white, and the background color as (black despite not rendering the background color, so its transparent). All in Interface Builder.

我已经设置了一个NSTextField,文本颜色为白色,背景颜色为(黑色,尽管没有渲染背景颜色,因此它是透明的)。全部在Interface Builder中。

The problem I am having is the cursor is black, and hardly visible. Does the cursor not represent the text color? Any ideas how I can fix this?

我遇到的问题是光标是黑色的,几乎看不到。光标不代表文字颜色吗?我有什么想法可以解决这个问题?

Otherwise, the NSTextField looks like it cannot be edited.

否则,NSTextField看起来无法编辑。

7 个解决方案

#1


16  

Your best bet is probably to use NSTextView and - (void)setInsertionPointColor:(NSColor *)color.

你最好的选择可能是使用NSTextView和 - (void)setInsertionPointColor:(NSColor *)颜色。

#2


28  

Since in practice the NSText* returned by -currentEditor for an NSTextField is always an NSTextView*, I added the following code to my custom NSTextField subclass:

实际上,由-currentEditor为NSTextField返回的NSText *始终是NSTextView *,我将以下代码添加到我的自定义NSTextField子类中:

-(BOOL) becomeFirstResponder
{
    BOOL    success = [super becomeFirstResponder];
    if( success )
    {
        // Strictly spoken, NSText (which currentEditor returns) doesn't
        // implement setInsertionPointColor:, but it's an NSTextView in practice.
        // But let's be paranoid, better show an invisible black-on-black cursor
        // than crash.
        NSTextView* textField = (NSTextView*) [self currentEditor];
        if( [textField respondsToSelector: @selector(setInsertionPointColor:)] )
            [textField setInsertionPointColor: [NSColor whiteColor]];
    }
    return success;
}

So if you're already replacing this class because you're doing custom background drawing, this might be a more encapsulated solution. Maybe there's even a way to move this up into NSCell, which would be cleaner since NSCell is the one doing the drawing and knowing the colors anyway.

因此,如果您已经在替换此类,因为您正在进行自定义背景绘制,那么这可能是一个更加封装的解决方案。也许甚至还有一种方法可以将其转移到NSCell中,因为NSCell是绘图并且无论如何都知道颜色的人。

#3


26  

TextField Insertion Point Color

NSTextField *textField = self.textField;
NSColor *insertionPointColor = [NSColor blueColor];

NSTextView *fieldEditor = (NSTextView*)[textField.window fieldEditor:YES
                                                           forObject:textField];
fieldEditor.insertionPointColor = insertionPointColor;

#4


11  

Assuming that you are wanting to set the color of the insertion caret and not the mouse cursor then the suggestion of using setInsertionPointColor: should work.

假设您要设置插入插入符号而不是鼠标光标的颜色,那么使用setInsertionPointColor:的建议应该可行。

However, you do not necessarily need to change from using NSTextField to NSTextView. The field editor for window that the NSTextField is in is an NSTextView. So when your NSTextField becomes the key view you could grab the field editor and call setInsertionPointColor: on that. You may need to reset the color when your field stops being the key view.

但是,您不一定需要从使用NSTextField更改为NSTextView。 NSTextField所在的窗口的字段编辑器是NSTextView。因此,当您的NSTextField成为关键视图时,您可以获取字段编辑器并调用setInsertionPointColor:on。当字段停止为关键视图时,您可能需要重置颜色。

You can get the field editor by using NSWindow's fieldEditor:forObject: or NSCell's fieldEditorForView:.

您可以使用NSWindow的fieldEditor:forObject:或NSCell的fieldEditorForView:来获取字段编辑器。

If you have a subclass of NSTextField you can have it use a custom subclass of NSTextFieldCell and override -(NSText*)setUpFieldEditorAttributes:(NSText*)textObj. In that method you can set the insertion point color once and it will stay while the field editor is active for this text field. Though when the field editor is moved to another edit field the insertion point color will remain unless you reset it.

如果您有NSTextField的子类,则可以使用NSTextFieldCell的自定义子类并覆盖 - (NSText *)setUpFieldEditorAttributes:(NSText *)textObj。在该方法中,您可以设置一次插入点颜色,并且在该文本字段的字段编辑器处于活动状态时它将保留。虽然当字段编辑器移动到另一个编辑字段时,插入点颜色将保留,除非您重置它。

#5


2  

Inspired by the great answer of Jon Steinmetz I created the following example.

灵感来自Jon Steinmetz的伟大答案,我创建了以下示例。

I added a NSSecureTextField to the application view and connected it to the IBOutlet of the member variable I placed into AppDelegate.

我在应用程序视图中添加了一个NSSecureTextField,并将其连接到放入AppDelegate的成员变量的IBOutlet。

@implementation AppDelegate

@synthesize password = m_password;

- (void)awakeFromNib {
    assert(m_password);
    self.password.backgroundColor = [NSColor blackColor];
}

Then I created a custom NSSecureTextField class. I noticed that is in some cases not enough to set the colors in awakeFromNib but I cannot give a reason for this.

然后我创建了一个自定义的NSSecureTextField类。我注意到在某些情况下还不足以设置awakeFromNib中的颜色,但我无法给出理由。

@implementation CustomSecureTextField

- (void)customize {
    // Customize the text and caret color.
    NSColor* foregroundColor = [NSColor whiteColor];
    self.textColor = foregroundColor;
    [[self.cell fieldEditorForView:self] setInsertionPointColor:foregroundColor];   
}

- (void)awakeFromNib {
    [self customize];
}

- (void)textDidBeginEditing:(NSNotification*)notification {
    // Called when the user inputs a character.
    [self customize];
}

- (void)textDidEndEditing:(NSNotification*)notification {
    // Called when the user clicks into the field for the first time.
    [self customize];   
}

- (void)textDidChange:(NSNotification*)notification {
    // Just in case ... for the paranoid programmer!
    [self customize];
}


@end

Note: Though, I do not understand why the background color cannot be set when I do this in the derived class like with the textColor. That would allow to get rid of the IBOutlet and the member variable.

注意:虽然,我不明白为什么在我使用textColor这样在派生类中执行此操作时无法设置背景颜色。这将允许摆脱IBOutlet和成员变量。

#6


2  

I've called insertionPointColor in viewDidLoad and app crashes.

我在viewDidLoad中调用了insertionPointColor,app崩溃了。

I fixed this by calling insertionPointColor on viewDidAppear.

我通过在viewDidAppear上调用insertionPointColor来修复此问题。

For Swift developers:

对于Swift开发人员:

Set insertionPointColor method into extension:

将insertionPointColor方法设置为扩展名:

extension NSTextField {
    public func customizeCursorColor(_ cursorColor: NSColor) {
        let fieldEditor = self.window?.fieldEditor(true, for: self) as! NSTextView
        fieldEditor.insertionPointColor = cursorColor
    }
}

and call

并打电话

 override func viewDidAppear() {
        super.viewDidAppear()
        textField.customizeCursorColor(NSColor.red)
    }

#7


0  

Swift 4 Solution

Swift 4解决方案

override func viewDidAppear() {
    super.viewDidAppear()
    guard let window = _textField.window, let fieldEditor = window.fieldEditor(true, for: _textField) as? NSTextView else { return }
    fieldEditor.insertionPointColor = .white
}

#1


16  

Your best bet is probably to use NSTextView and - (void)setInsertionPointColor:(NSColor *)color.

你最好的选择可能是使用NSTextView和 - (void)setInsertionPointColor:(NSColor *)颜色。

#2


28  

Since in practice the NSText* returned by -currentEditor for an NSTextField is always an NSTextView*, I added the following code to my custom NSTextField subclass:

实际上,由-currentEditor为NSTextField返回的NSText *始终是NSTextView *,我将以下代码添加到我的自定义NSTextField子类中:

-(BOOL) becomeFirstResponder
{
    BOOL    success = [super becomeFirstResponder];
    if( success )
    {
        // Strictly spoken, NSText (which currentEditor returns) doesn't
        // implement setInsertionPointColor:, but it's an NSTextView in practice.
        // But let's be paranoid, better show an invisible black-on-black cursor
        // than crash.
        NSTextView* textField = (NSTextView*) [self currentEditor];
        if( [textField respondsToSelector: @selector(setInsertionPointColor:)] )
            [textField setInsertionPointColor: [NSColor whiteColor]];
    }
    return success;
}

So if you're already replacing this class because you're doing custom background drawing, this might be a more encapsulated solution. Maybe there's even a way to move this up into NSCell, which would be cleaner since NSCell is the one doing the drawing and knowing the colors anyway.

因此,如果您已经在替换此类,因为您正在进行自定义背景绘制,那么这可能是一个更加封装的解决方案。也许甚至还有一种方法可以将其转移到NSCell中,因为NSCell是绘图并且无论如何都知道颜色的人。

#3


26  

TextField Insertion Point Color

NSTextField *textField = self.textField;
NSColor *insertionPointColor = [NSColor blueColor];

NSTextView *fieldEditor = (NSTextView*)[textField.window fieldEditor:YES
                                                           forObject:textField];
fieldEditor.insertionPointColor = insertionPointColor;

#4


11  

Assuming that you are wanting to set the color of the insertion caret and not the mouse cursor then the suggestion of using setInsertionPointColor: should work.

假设您要设置插入插入符号而不是鼠标光标的颜色,那么使用setInsertionPointColor:的建议应该可行。

However, you do not necessarily need to change from using NSTextField to NSTextView. The field editor for window that the NSTextField is in is an NSTextView. So when your NSTextField becomes the key view you could grab the field editor and call setInsertionPointColor: on that. You may need to reset the color when your field stops being the key view.

但是,您不一定需要从使用NSTextField更改为NSTextView。 NSTextField所在的窗口的字段编辑器是NSTextView。因此,当您的NSTextField成为关键视图时,您可以获取字段编辑器并调用setInsertionPointColor:on。当字段停止为关键视图时,您可能需要重置颜色。

You can get the field editor by using NSWindow's fieldEditor:forObject: or NSCell's fieldEditorForView:.

您可以使用NSWindow的fieldEditor:forObject:或NSCell的fieldEditorForView:来获取字段编辑器。

If you have a subclass of NSTextField you can have it use a custom subclass of NSTextFieldCell and override -(NSText*)setUpFieldEditorAttributes:(NSText*)textObj. In that method you can set the insertion point color once and it will stay while the field editor is active for this text field. Though when the field editor is moved to another edit field the insertion point color will remain unless you reset it.

如果您有NSTextField的子类,则可以使用NSTextFieldCell的自定义子类并覆盖 - (NSText *)setUpFieldEditorAttributes:(NSText *)textObj。在该方法中,您可以设置一次插入点颜色,并且在该文本字段的字段编辑器处于活动状态时它将保留。虽然当字段编辑器移动到另一个编辑字段时,插入点颜色将保留,除非您重置它。

#5


2  

Inspired by the great answer of Jon Steinmetz I created the following example.

灵感来自Jon Steinmetz的伟大答案,我创建了以下示例。

I added a NSSecureTextField to the application view and connected it to the IBOutlet of the member variable I placed into AppDelegate.

我在应用程序视图中添加了一个NSSecureTextField,并将其连接到放入AppDelegate的成员变量的IBOutlet。

@implementation AppDelegate

@synthesize password = m_password;

- (void)awakeFromNib {
    assert(m_password);
    self.password.backgroundColor = [NSColor blackColor];
}

Then I created a custom NSSecureTextField class. I noticed that is in some cases not enough to set the colors in awakeFromNib but I cannot give a reason for this.

然后我创建了一个自定义的NSSecureTextField类。我注意到在某些情况下还不足以设置awakeFromNib中的颜色,但我无法给出理由。

@implementation CustomSecureTextField

- (void)customize {
    // Customize the text and caret color.
    NSColor* foregroundColor = [NSColor whiteColor];
    self.textColor = foregroundColor;
    [[self.cell fieldEditorForView:self] setInsertionPointColor:foregroundColor];   
}

- (void)awakeFromNib {
    [self customize];
}

- (void)textDidBeginEditing:(NSNotification*)notification {
    // Called when the user inputs a character.
    [self customize];
}

- (void)textDidEndEditing:(NSNotification*)notification {
    // Called when the user clicks into the field for the first time.
    [self customize];   
}

- (void)textDidChange:(NSNotification*)notification {
    // Just in case ... for the paranoid programmer!
    [self customize];
}


@end

Note: Though, I do not understand why the background color cannot be set when I do this in the derived class like with the textColor. That would allow to get rid of the IBOutlet and the member variable.

注意:虽然,我不明白为什么在我使用textColor这样在派生类中执行此操作时无法设置背景颜色。这将允许摆脱IBOutlet和成员变量。

#6


2  

I've called insertionPointColor in viewDidLoad and app crashes.

我在viewDidLoad中调用了insertionPointColor,app崩溃了。

I fixed this by calling insertionPointColor on viewDidAppear.

我通过在viewDidAppear上调用insertionPointColor来修复此问题。

For Swift developers:

对于Swift开发人员:

Set insertionPointColor method into extension:

将insertionPointColor方法设置为扩展名:

extension NSTextField {
    public func customizeCursorColor(_ cursorColor: NSColor) {
        let fieldEditor = self.window?.fieldEditor(true, for: self) as! NSTextView
        fieldEditor.insertionPointColor = cursorColor
    }
}

and call

并打电话

 override func viewDidAppear() {
        super.viewDidAppear()
        textField.customizeCursorColor(NSColor.red)
    }

#7


0  

Swift 4 Solution

Swift 4解决方案

override func viewDidAppear() {
    super.viewDidAppear()
    guard let window = _textField.window, let fieldEditor = window.fieldEditor(true, for: _textField) as? NSTextView else { return }
    fieldEditor.insertionPointColor = .white
}