8

我正在使用 NSTextField 并使用 setupFieldEditorAttributes: 方法自定义 fieldEditor。这允许我为所选文本设置自定义前景色和背景色,这很重要,因为我的 textField 有黑色背景和白色文本。通常,这可以正常工作。但是,当我停用应用程序并且窗口不再是关键时,我的设置似乎被覆盖了。fieldEditor NSTextView 仍然存在,但绘图更改为白色文本颜色和浅灰色选择颜色(默认值)。有人对我如何自定义此绘图有建议吗?

4

2 回答 2

0

您可以覆盖 [NSWindow willReturnFieldEditor:toObject:] 并返回自定义 NSTextView 并更改选择颜色。

于 2012-12-05T18:51:34.030 回答
0

受到这个问题的答案的启发,解决方案是创建一个 NSLayoutManager 的覆盖,它根据拥有它的 NSText 视图的第一响应者状态自定义突出显示的方式。

如果与此自定义布局管理器关联的文本视图是第一响应者,则它使用 macOS 提供的颜色绘制选择。如果文本视图不是第一响应者,它将使用文本视图的背景颜色作为选择颜色,除非通过 setCustomInactiveColor 方法提供了自定义颜色。

// ---------------------------------------------------------------------------
//  IZLayoutManager CLASS
// ---------------------------------------------------------------------------
// Override NSLayoutManager to change how the currently selected text is
// highlighted when the owning NSTextView is not the first responder.

@interface IZLayoutManager : NSLayoutManager
{
}
-(instancetype)initWithOwningTextView:(NSTextView*)inOwningTextView;
@property (nullable, assign, nonatomic) NSTextView* owningTextView;
@property (nullable, strong, nonatomic) NSColor* customInactiveColor;
@end

@implementation IZLayoutManager

- (instancetype)initWithOwningTextView:(NSTextView*)inOwningTextView
{
    self = [super init];
    
    if (self)  {
        self.owningTextView = inOwningTextView;
    }
    
    return self;
}

- (void) dealloc
{
    // my project is non-ARC; so we maually release any custom color
    // we received; in non-ARC projects this is probably not necessary
    if (self.customInactiveColor != NULL) {
        [self.customInactiveColor release];
        self.customInactiveColor = NULL;
    }
    [super dealloc];
}

// see extensive description of fillBackgroundRectArray in NSLayoutManager.h
// TL;DR: if you change the background color here, you must restore it before
// returning from this call

- (void) fillBackgroundRectArray:(const NSRect *)rectArray count:(NSUInteger)rectCount forCharacterRange:(NSRange)charRange color:(NSColor *)color
{
    BOOL needToReestoreColor = NO;
    
    if (self.owningTextView != NULL && [[self.owningTextView window] firstResponder] != self.owningTextView) {
        if (self.customInactiveColor != NULL) {
            [self.customInactiveColor setFill];
        } else {
            [[self.owningTextView backgroundColor] setFill];
        }
        needToReestoreColor = true;
    }
    
    [super fillBackgroundRectArray:rectArray count:rectCount forCharacterRange:charRange color:color];
    
    if (needToReestoreColor) {
        [color setFill];
    }
}
@end

然后,在你分配了 NSTextView 之后,你需要这样做:

NSTextView* myTextView = ... // get a reference to your text view

// allocate our custom layout manager
IZLayoutManager* layoutManager = [[[IZLayoutManager alloc] initWithOwningTextView:self] autorelease];

// if you want to use a color other than the background for
// the selected text, uncomment the following line and
// supply your desired color

// [layoutManager setCustomInactiveColor:[NSColor redColor]];

[[myTextView textContainer] replaceLayoutManager:layoutManager];
于 2021-07-31T05:32:02.860 回答