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

Posted

技术标签:

【中文标题】NSTextField - 黑色背景上的白色文本,但黑色光标【英文标题】:NSTextField - White text on black background, but black cursor 【发布时间】:2011-01-16 12:42:18 【问题描述】:

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

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

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

【问题讨论】:

请把 uliwitness 的回答标记为正确的 【参考方案1】:

我在 swift 中使用此代码

 if let editor = textField.currentEditor() as? NSTextView
     editor.insertionPointColor = myColor ?? .black
 

【讨论】:

请在发布新答案之前检查日期。这个问题差不多12岁了。【参考方案2】:

最简单的方法是

 override func viewDidAppear() 
    if let fieldEditor = self.view.window?.fieldEditor(true, for: self) as? NSTextView
        fieldEditor.insertionPointColor = NSColor.black
    
 

【讨论】:

【参考方案3】:

如果你使用Objective-C运行时选择器捕获结合uliwitness's solution,可以不用继承NSTextField就可以实现,这里我以RxCocoa的methodInvoked为例:

import Cocoa
import RxCocoa

extension NSTextField 
    func withCursorColor(_ color: NSColor) 
        rx.methodInvoked(#selector(becomeFirstResponder))
            .subscribe(onNext:  [unowned self] _ in
                guard let editor = self.currentEditor() as? NSTextView else  return 
                editor.insertionPointColor = color
            )
            .disposed(by: rx.disposeBag)
    


【讨论】:

【参考方案4】:

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

【讨论】:

【参考方案5】:

我在viewDidLoad 中调用了insertionPointColor 并且应用程序崩溃了。

我通过在viewDidAppear 上调用insertionPointColor 解决了这个问题。

Swift 开发者:

在扩展中设置insertionPointColor方法:

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

并调用

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

【讨论】:

【参考方案6】:

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

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

您可以使用NSWindowfieldEditor:forObject:NSCellfieldEditorForView:获取字段编辑器。

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

【讨论】:

这是更改 NSSecureTextField 上插入点颜色的绝妙方法。谢谢! 但是fieldEditor:forObject: 返回一个NSText 对象。我无法通过NSText 拨打setInsertionPointColor: 我无法再访问我的原始代码,但 NSTextView 是 NSText 的子类,如果您查看 NSTextView 的接口,它有一个 isFieldEditor 方法。您可以尝试使用 isKindOfClass: 来测试 NSText 是否真的是 NSTextView。另一件事是尝试使用 NSCell 的 fieldEditorForView: 就像在 JJD 的回答中一样。 这是不正确的。 textDidBeginEditing:textDidEndEditing: 不会通知您 NSTextField 的键状态的变化。这些方法只会在用户开始在字段中输入文本时触发。如果您只是单击该字段使其成为键,则不会触发这些方法,因此您将看到一个黑色插入符号,直到您键入第一个字符。【参考方案7】:

TextField 插入点颜色

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

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

【讨论】:

只要确保在 viewDidAppear 中调用它,因为 fieldEditor 在 vi​​ewDidLoad 或 viewWillAppear 中仍为 nil【参考方案8】:

由于实际上 -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;

因此,如果您因为正在绘制自定义背景而已经替换了此类,那么这可能是一个更加封装的解决方案。也许甚至有一种方法可以将它移到 NSCell 中,这样会更干净,因为 NSCell 是负责绘图并知道颜色的。

【讨论】:

这确实应该被标记为正确答案;使用其他答案中提出的 textDidBegin/end: 委托方法不会更改插入符号的颜色,直到用户开始输入。这个立即改变它的焦点。 您可能需要添加一个相应的-(BOOL) resignFirstResponder 方法,将颜色改回黑色,因为相关字段编辑器由窗口中的所有文本字段共享。将其设置为白色可能不是一个好主意,因为其他字段不会自动将其设置为黑色。 请注意,resignFirstResponder 在这种情况下将不起作用,因为当字段编辑器成为第一响应者时,它将在 becomeFirstResponder 之后立即调用。【参考方案9】:

受到Jon Steinmetz 的精彩回答的启发,我创建了以下示例。

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

@implementation AppDelegate

@synthesize password = m_password;

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

然后我创建了一个自定义 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

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

【讨论】:

可能值得调用 super 的您要覆盖的函数的实现。【参考方案10】:

您最好的选择可能是使用 NSTextView 和 - (void)setInsertionPointColor:(NSColor *)color

【讨论】:

没有。最好的办法是继承 NSTextField,如下 uliwitness 所述。

以上是关于NSTextField - 黑色背景上的白色文本,但黑色光标的主要内容,如果未能解决你的问题,请参考以下文章

DT::DataTables 中第一列的黑色背景和白色字体

叠加在图像上时,使文本显示为白色,具有半透明的黑色背景

带有黑色背景的 alpha 图像绘制其他白色...?

NSTextField(标签)属性文本:选择

如何在白色背景上的Open GL ES中显示彩色纹理画笔?

图像背景后的黑色背景(不透明度 0.6),文本为不透明度 1