NSTextView рисует черный на почти черном в темном режиме

Когда я создаю приложение для macOS в темном режиме, некоторые из моих текстовых представлений (NSTextView) отображают черный текст на почти черном фоне. В Интерфейсном Разработчике, в Инспекторе Атрибутов, «Цвет текста» установлен на системный «По умолчанию (Цвет текста)», что я считаю правильным. Действительно, в Интерфейсном Разработчике этот текст отображается белым в темном режиме и черным в светлом режиме, как это необходимо. Я искал в своем коде какие-либо строки, в которых я мог бы программно установить цвет текста в этом представлении на черный, но не нашел ни одной. Почему мой текст всегда черный?


person Jerry Krinock    schedule 16.10.2018    source источник


Ответы (4)


Я заметил, что у ошибочных текстовых представлений есть их «атрибутированная строка», привязанная с помощью привязок какао к методам, которые возвращают простые, а не атрибуты NSString объекты. Вероятно, я сделал это, потому что я был ленив, когда писал это приложение много лет назад, и оно работало нормально. Это несоответствие оказалось проблемой. Исправление состоит в том, чтобы изменить эти методы для возврата NSAttributedString со словарем атрибутов, содержащим пару ключ / значение.

NSForegroundColorAttributeName : NSColor.controlTextColor

Вероятно, произошло то, что Cocoa был разработан, чтобы делать то, что вы, вероятно, хотите, когда привязка строки с атрибутами получает строку без атрибута. Вместо запрета исключения, Какао применяет некоторые атрибуты «по умолчанию», которые включают черный цвет текста, который был по умолчанию в macOS с 1984 года - это было совершенно разумно, пока не появился Темный режим! Что ж, было бы неплохо со стороны Apple изменить этот цвет по умолчанию с черного на controlTextColor, но, видимо, они этого не сделали.

Вывод: Мы больше не можем обойтись без привязки строки с атрибутами текстового представления к простой строке без атрибутов.

Или вы можете использовать ответ @Ely и привязать к value. Но если вы попробуете это и не увидите value привязку в Bindings Inspector, но увидите data привязку, это связано с этими замечаниями в документации NSTextField:

Привязка [value] доступна только в том случае, если NSTextView настроен для отображения с использованием одного шрифта.

и позже

Привязка [data] доступна только в том случае, если NSTextView настроен на использование нескольких шрифтов.

Оказывается, под настроенным на использование нескольких шрифтов они подразумевают то, что в инспекторе атрибутов установлен флажок Разрешить форматированный текст. И наоборот, настроено для отображения с использованием одного шрифта означает, что флажок Разрешить форматированный текст снят.

person Jerry Krinock    schedule 16.10.2018

У меня сработало после использования этого кода (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 и преобразовании из / в монтажный и внешний форматы значения цвета преобразуются между контекстами модели и рендеринга. Обратите внимание, что алгоритм преобразования цвета сжимает диапазон яркости и, следовательно, не сохраняет точную двустороннюю точность между светлым и темным появлением. Он может не подходить для создания форматированного текста, поэтому рекомендуется предоставить пользователям команду или предпочтение для просмотра и редактирования своих документов без этого параметра или в облегченном режиме. * /

person Douglas Frari    schedule 17.03.2020
comment
Спасибо за ответ. Странно, что описание этой переменной в apple docs до сих пор пусто. - person Kaunteya; 15.08.2020

Если вы используете обычный текст в NSTextView (например, потому что вам нужен scrollview), просто привяжите к свойству value вместо attributedString. Эта привязка будет использовать настройку цвета текста элемента управления и отлично работает с темным режимом.

person Ely    schedule 10.11.2018
comment
Я новичок в привязке, но не вижу value на панели свойств. Я попробовал Value Path, но ничего не вышло. - person Mr Rogers; 16.04.2019
comment
Привязка к значению не позволяет правильно изменить цвет в темном режиме, хотя текст отображается правильно. [[self commentsView] bind: @value toObject: [[[сам документ] windowController] itemsController] withKeyPath: @ selection.userComments options: valueOptions]; - person Trygve; 12.08.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)
    }
}
person ToddX61    schedule 23.04.2019