我正在使用NSTextField并使用setupFieldEditorAttributes:方法自定义fieldEditor。这允许我为所选文本设置自定义前景色和背景色,这很重要,因为我的textField有黑色背景和白色文本。一般来说,这很好。但是,当我取消激活应用程序并且窗口不再是键时,我的设置似乎被覆盖。 fieldEditor NSTextView保留在那里,但绘制更改为白色文本颜色和浅灰色选择颜色(默认值)。有没有人有关于如何自定义此绘图的建议?
答案 0 :(得分:0)
您可以覆盖[NSWindow willReturnFieldEditor:toObject:]并返回更改选择颜色的自定义NSTextView。
答案 1 :(得分:0)
受到 the answer to this question 的启发,解决方案是创建 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];