MacOSアプリをダークモードでビルドすると、一部のテキストビュー(NSTextView)で、ほぼ黒の背景に黒のテキストがレンダリングされます。インターフェイスビルダーの属性インスペクターで、「テキストの色」がシステムの「デフォルト(テキストの色)」に設定されています。実際、Interface Builderでは、このテキストはダークモードでは白に、ライトモードでは黒にレンダリングされます。このビューのテキストの色をプログラムで黒に設定している可能性のある行をコードで検索しましたが、何も見つかりません。テキストが常に黒くなるのはなぜですか?
誤ったテキストビューには、Cocoaバインディングを使用して、属性付きのNSStringオブジェクトではなくプレーンを返すメソッドに「属性付き文字列」がバインドされていることに気付きました。私が何年も前にこのアプリを書いたときに私が怠惰だったので、おそらくこれを行い、それはうまくいきました。この不一致が問題であることが判明しました。修正は、これらのメソッドを変更して、キーと値のペアを含む属性ディクショナリでNSAttributedStringを返すことです。
NSForegroundColorAttributeName : NSColor.controlTextColor
おそらく起こったのは、Cocoaが属性文字列バインディングが非属性文字列を取得したときにおそらく何をしたいかに設計されたことです。 Cocoaは例外を回避する代わりに、1984年以来macOSのデフォルトであった黒いテキストの色を含むいくつかの「デフォルト」属性を適用します-ダークモードが登場するまで完全に理にかなっています!まあ、それはAppleのこのデフォルトを黒からcontrolTextColorに変更するのは素晴らしいことでしたが、明らかにそうではありませんでした。
結論:テキストビューの属性付き文字列を属性のないプレーンな文字列にバインドすることで、もはや回避できません。
または、@ Elyの回答を使用してvalue
にバインドできます。しかし、それを試して、Bindings Inspectorにvalue
バインディングが表示されず、data
バインディングが表示される場合、それはNSTextFieldのドキュメントにあるこれらの注釈が原因です。
[value
]バインディングは、NSTextViewが単一のフォントとして表示するように構成されている場合にのみ使用できます。
以降
[data
]バインディングは、NSTextViewが複数のフォントを許可するように構成されている場合にのみ使用できます。
複数のフォントを許可するように構成とは、属性インスペクタでリッチテキストを許可するチェックボックスがオンになっているという意味です。逆に、単一のフォントとして表示するように構成は、リッチテキストを許可チェックボックスがオフであることを意味します。
NSTextViewでプレーンテキストを使用する場合(たとえば、スクロールビューが必要なため)、value
ではなくattributedString
プロパティにバインドするだけです。このバインディングは、コントロールのテキストの色設定を使用し、ダークモードで完全に機能します。
「プレーン」(属性なし)文字列用のNSTextView拡張。ライトモードまたはダークモードで動作します。
extension NSTextView {
static let DefaultAttribute =
[NSAttributedString.Key.foregroundColor: NSColor.textColor] as [NSAttributedString.Key: Any]
var stringValue: String {
return textStorage?.string ?? ""
}
func setString(_ string: String) {
textStorage?.mutableString.setString("")
append(string)
}
func append(_ string: String) {
let attributedText = NSAttributedString(string: string, attributes: NSTextView.DefaultAttribute)
textStorage?.append(attributedText)
}
}
このコードを使用した後、私にとってはうまくいきました(macOS Catalinaバージョン10.15.3):
if #available(OSX 10.14, *) {
textView.usesAdaptiveColorMappingForDarkAppearance = true
} else {
// Fallback on earlier versions - do nothing
}
私はこれがメソッドに文書化されているのを見つけました:
/ ***************************ダークモード******************** *******
YESの場合、アダプティブカラーマッピングモードを有効にします。暗い効果的な外観のこのモードでは、NSTextViewは、モデルオブジェクトNSTextStorageに出入りするたびに明るさを反転させることにより、すべての色をNSColorTypeComponentBasedでマップします。たとえば、レンダリング、NSColorPanelおよびNSFontManagerとの相互作用、およびペーストボードと外部フォーマット間の変換では、モデルとレンダリングコンテキスト間でカラー値が変換されます。色変換アルゴリズムは明るさの範囲を圧縮するため、明るい外観と暗い外観の間の往復忠実度は保持されないことに注意してください。リッチテキストのオーサリングには適していない可能性があるため、このオプションなしで、またはライトモードでユーザーがドキュメントを表示および編集するためのコマンドまたは設定を提供することをお勧めします。 * /