8

[NSTextView selectedTextAttributes]背景色とほぼ同じ色 (構文の強調表示) をユーザーが選択できるようにするため、私のアプリではの既定値は使用できません。

適切な色を決定するための数学を書きました。これを使用して設定できます。

textView.selectedTextAttributes = @{
  NSBackgroundColorAttributeName: [NSColor yellowColor],
  NSForegroundColorAttributeName: [NSColor redColor]
  };

ただし、ウィンドウがバックグラウンドにある場合でも、システムのデフォルトのライト グレーが使用されます。

上記のコードのスクリーンショットを、アクティブなウィンドウと非アクティブなウィンドウで添付しました。— 非アクティブなウィンドウの選択したテキストの背景色を変更するにはどうすればよいですか?

アクティブ 非活性

4

3 に答える 3

11

の描画方法をオーバーライドすることで、色をオーバーライドできます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()
    }
}

NSTextViewのレイアウトマネージャーをそれに置き換えます。

textView.textContainer!.replaceLayoutManager(layoutManager1)

これが完全な作業例です。


@Kyle が の理由を尋ねるのでsetFill、いくつかの更新を追加します。

アップルのマニュアルから:

... charRange および color パラメータは、情報提供のみを目的として渡されます。色はすでにグラフィックス状態で設定されています。何らかの理由で変更した場合は、このメソッドから戻る前に復元する必要があります。...

つまり、他の色を呼び出しに渡しても効果はなく、呼び出しで機能させるsuper必要があるだけです 。また、マニュアルでは、元のものに戻す必要があります。NSColor.setFillsuper

于 2016-01-03T15:49:33.857 に答える
5

It's not when the window is in the background it's when the NSTextView is not selected. I don't think you can change that behavior. enter image description here

You could create an attributed string and add the NSBackgroundColorAttributeName attribute to the range of the selected text when it loses focus. The attributed string stays the same color even when the focus is lost.

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];

enter image description here

EDIT by Abhi Beckert: this is how I implemented this answer (note I also had to disable the built in selected text attributes, or else they override the ones I'm setting):

@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
于 2013-05-11T02:33:15.127 に答える