如何在后台窗口中设置[NSTextView selectedTextAttributes]?

Abh*_*ert 8 cocoa objective-c nstextview

[NSTextView selectedTextAttributes]我的应用程序中的默认值无法使用,因为我允许用户选择与背景颜色几乎完全相同的颜色(语法突出显示).

我已经写了一些数学来确定合适的颜色,可以使用它来设置它:

textView.selectedTextAttributes = @{
  NSBackgroundColorAttributeName: [NSColor yellowColor],
  NSForegroundColorAttributeName: [NSColor redColor]
  };
Run Code Online (Sandbox Code Playgroud)

但是当窗口在后台时,它仍然使用系统默认的浅灰色.

我已经使用活动与非活动窗口附加了上述代码的屏幕截图. - 如何更改非活动窗口的选定文本背景颜色?

活性 待用

Eon*_*nil 10

您可以通过覆盖绘图方法来覆盖颜色NSLayoutManager.

final class LayoutManager1: NSLayoutManager {
    override func fillBackgroundRectArray(rectArray: UnsafePointer<NSRect>, count rectCount: Int, forCharacterRange charRange: NSRange, color: NSColor) {
        let color1 = color == NSColor.secondarySelectedControlColor() ? NSColor.redColor() : color
        color1.setFill()
        super.fillBackgroundRectArray(rectArray, count: rectCount, forCharacterRange: charRange, color: color1)
        color.setFill()
    }
}
Run Code Online (Sandbox Code Playgroud)

并将其替换为NSTextView布局管理器.

textView.textContainer!.replaceLayoutManager(layoutManager1)
Run Code Online (Sandbox Code Playgroud)

这是完整的工作示例.


正如@Kyle要求的原因setFill,我添加了一些更新.

来自Apple手册:

... charRange和颜色参数仅用于提供信息; 颜色已在图形状态中设置.如果由于任何原因您修改它,则必须在从此方法返回之前将其恢复....

这意味着将其他颜色传入super呼叫无效,您只需要 NSColor.setFill使其与super呼叫一起工作即可.此外,手册需要将其设置回原始版本.


Ber*_*lue 5

当窗口处于后台时,不是在未选择NSTextView时.我认为你不能改变这种行为. 在此输入图像描述

您可以创建一个属性字符串,并在失去焦点时将NSBackgroundColorAttributeName属性添加到所选文本的范围内.即使焦点丢失,属性字符串仍保持相同的颜色.

NSMutableAttributedString *string = [[NSMutableAttributedString alloc] initWithString:@"hello world"];
[string addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(1, 7)];
[string addAttribute:NSBackgroundColorAttributeName value:[NSColor yellowColor] range:NSMakeRange(1, 7)];
[self.myTextView insertText:string];
Run Code Online (Sandbox Code Playgroud)

在此输入图像描述

由Abhi Beckert编辑:这是我实现这个答案的方式(注意我还必须禁用内置的选定文本属性,否则它们会覆盖我正在设置的那些):

@implementation MyTextView

- (id)initWithCoder:(NSCoder *)aDecoder
{
  if (!(self = [super initWithCoder:aDecoder]))
    return nil;

  // disable built in selected text attributes
  self.selectedTextAttributes = @{};

  return self;
}

- (id)initWithFrame:(NSRect)frameRect textContainer:(NSTextContainer *)container
{
  if (!(self = [super initWithFrame:frameRect textContainer:container]))
    return nil;

  // disable built in selected text attributes
  self.selectedTextAttributes = @{};

  return self;
}

- (void)setSelectedRanges:(NSArray *)ranges affinity:(NSSelectionAffinity)affinity stillSelecting:(BOOL)stillSelectingFlag
{
  // remove from old ranges
  for (NSValue *value in self.selectedRanges) {
    if (value.rangeValue.length == 0)
      continue;

    [self.textStorage removeAttribute:NSBackgroundColorAttributeName range:value.rangeValue];
  }

  // apply to new ranges
  for (NSValue *value in ranges) {
    if (value.rangeValue.length == 0)
      continue;

    [self.textStorage addAttribute:NSBackgroundColorAttributeName value:[NSColor yellowColor] range:value.rangeValue];
  }

  [super setSelectedRanges:ranges affinity:affinity stillSelecting:stillSelectingFlag];
}

@end
Run Code Online (Sandbox Code Playgroud)