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

时间:2010-02-13 16:47:30

标签: objective-c macos cocoa customization nstextfield

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

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

否则,NSTextField似乎无法编辑。

8 个答案:

答案 0 :(得分:30)

因为在实践中,-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是绘图并且知道颜色的人,因此它会更清晰。

答案 1 :(得分:27)

TextField插入点颜色

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

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

答案 2 :(得分:17)

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

答案 3 :(得分:14)

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

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

您可以使用NSWindow的{​​{1}}或fieldEditor:forObject:的{​​{1}}来获取字段编辑器。

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

答案 4 :(得分:2)

受到Jon Steinmetz的好答案的启发,我创建了以下示例。

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

@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和成员变量。

答案 5 :(得分:2)

我在insertionPointColor中呼叫viewDidLoad并且应用崩溃了。

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

对于 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 :(得分:2)

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
}

答案 7 :(得分:0)

如果结合使用{-{3}}和Objective-C运行时选择器捕获,则无需继承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)
    }
}