Когда я создаю приложение для macOS в темном режиме, некоторые из моих текстовых представлений (NSTextView) отображают черный текст на почти черном фоне. В Интерфейсном Разработчике, в Инспекторе Атрибутов, «Цвет текста» установлен на системный «По умолчанию (Цвет текста)», что я считаю правильным. Действительно, в Интерфейсном Разработчике этот текст отображается белым в темном режиме и черным в светлом режиме, как это необходимо. Я искал в своем коде какие-либо строки, в которых я мог бы программно установить цвет текста в этом представлении на черный, но не нашел ни одной. Почему мой текст всегда черный?
NSTextView рисует черный на почти черном в темном режиме
Ответы (4)
Я заметил, что у ошибочных текстовых представлений есть их «атрибутированная строка», привязанная с помощью привязок какао к методам, которые возвращают простые, а не атрибуты NSString объекты. Вероятно, я сделал это, потому что я был ленив, когда писал это приложение много лет назад, и оно работало нормально. Это несоответствие оказалось проблемой. Исправление состоит в том, чтобы изменить эти методы для возврата NSAttributedString со словарем атрибутов, содержащим пару ключ / значение.
NSForegroundColorAttributeName : NSColor.controlTextColor
Вероятно, произошло то, что Cocoa был разработан, чтобы делать то, что вы, вероятно, хотите, когда привязка строки с атрибутами получает строку без атрибута. Вместо запрета исключения, Какао применяет некоторые атрибуты «по умолчанию», которые включают черный цвет текста, который был по умолчанию в macOS с 1984 года - это было совершенно разумно, пока не появился Темный режим! Что ж, было бы неплохо со стороны Apple изменить этот цвет по умолчанию с черного на controlTextColor, но, видимо, они этого не сделали.
Вывод: Мы больше не можем обойтись без привязки строки с атрибутами текстового представления к простой строке без атрибутов.
Или вы можете использовать ответ @Ely и привязать к value
. Но если вы попробуете это и не увидите value
привязку в Bindings Inspector, но увидите data
привязку, это связано с этими замечаниями в документации NSTextField:
Привязка [value
] доступна только в том случае, если NSTextView настроен для отображения с использованием одного шрифта.
и позже
Привязка [data
] доступна только в том случае, если NSTextView настроен на использование нескольких шрифтов.
Оказывается, под настроенным на использование нескольких шрифтов они подразумевают то, что в инспекторе атрибутов установлен флажок Разрешить форматированный текст. И наоборот, настроено для отображения с использованием одного шрифта означает, что флажок Разрешить форматированный текст снят.
У меня сработало после использования этого кода (macOS Catalina версии 10.15.3):
if #available(OSX 10.14, *) {
textView.usesAdaptiveColorMappingForDarkAppearance = true
} else {
// Fallback on earlier versions - do nothing
}
Я нашел это задокументированным в методе:
/ ************************** Темный режим ******************** *******
Если ДА, включает режим адаптивного отображения цветов. В этом режиме под эффектом темноты NSTextView сопоставляет все цвета с помощью NSColorTypeComponentBased, инвертируя яркость всякий раз, когда они входят и выходят из объекта модели, NSTextStorage. Например, при рендеринге, взаимодействии с NSColorPanel и NSFontManager и преобразовании из / в монтажный и внешний форматы значения цвета преобразуются между контекстами модели и рендеринга. Обратите внимание, что алгоритм преобразования цвета сжимает диапазон яркости и, следовательно, не сохраняет точную двустороннюю точность между светлым и темным появлением. Он может не подходить для создания форматированного текста, поэтому рекомендуется предоставить пользователям команду или предпочтение для просмотра и редактирования своих документов без этого параметра или в облегченном режиме. * /
Если вы используете обычный текст в NSTextView (например, потому что вам нужен scrollview), просто привяжите к свойству value
вместо attributedString
. Эта привязка будет использовать настройку цвета текста элемента управления и отлично работает с темным режимом.
value
на панели свойств. Я попробовал Value Path
, но ничего не вышло.
- person Mr Rogers; 16.04.2019
Расширение 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)
}
}