web-dev-qa-db-fra.com

NSTextView dessine du noir sur presque noir en mode sombre

Lorsque je crée mon application macOS en mode sombre, certaines de mes vues de texte (NSTextView) affichent du texte noir sur un fond presque noir. Dans Interface Builder, dans l'inspecteur des attributs, la "Couleur du texte" est définie sur le système "Par défaut (Couleur du texte)", ce qui, à mon avis, est correct. En effet, dans Interface Builder, ce texte est rendu blanc en mode sombre et noir en mode clair, comme souhaité. J'ai recherché dans mon code toutes les lignes où je pourrais définir par programme la couleur du texte dans cette vue sur noir, mais je n'en trouve aucune. Pourquoi mon texte est-il toujours noir?

14
Jerry Krinock

J'ai remarqué que les vues de texte errantes ont leur "chaîne attribuée" liée, avec des liaisons Cocoa, à des méthodes qui retournent des objets NSString simples et non attribués. J'ai probablement fait cela parce que j'étais paresseux lorsque j'ai écrit cette application il y a des années, et cela a bien fonctionné. Cette inadéquation s'est avérée être le problème. Le correctif consiste à modifier ces méthodes pour renvoyer un NSAttributedString, avec un dictionnaire d'attributs contenant la paire clé/valeur

NSForegroundColorAttributeName : NSColor.controlTextColor

Ce qui s'est probablement passé, c'est que Cocoa a été conçu pour faire ce que vous voulez probablement lorsqu'une liaison de chaîne attribuée obtient une chaîne non attribuée. Au lieu de bloquer une exception, Cocoa applique certains attributs "par défaut", qui incluent la couleur du texte noir qui est la valeur par défaut de macOS depuis 1984 - tout à fait sensée jusqu'à l'arrivée du mode sombre! Eh bien, cela aurait pu être bien de Apple pour changer cette valeur par défaut du noir en controlTextColor, mais apparemment ils ne l'ont pas fait.

Conclusion: Nous ne pouvons plus nous passer de la liaison de la chaîne attribuée d'une vue texte à une chaîne non attribuée.

Ou, vous pouvez utiliser la réponse de @Ely et vous lier à value. Mais si vous essayez cela et ne voyez pas de liaison value dans l'inspecteur de liaisons, mais voyez une liaison data, c'est à cause de ces remarques dans la documentation NSTextField:

La liaison [value] n'est disponible que lorsque NSTextView est configuré pour s'afficher en utilisant une seule police.

et ensuite

La liaison [data] n'est disponible que lorsque NSTextView est configuré pour autoriser plusieurs polices.

Cela change ce qu'ils entendent par configuré pour autoriser plusieurs polices est que, dans l'inspecteur des attributs, le autorise le texte enrichi la case est cochée. Inversement, configuré pour afficher en utilisant une seule police signifie que le autorise le texte enrichi la case à cocher est désactivée.

8
Jerry Krinock

Si vous utilisez du texte brut dans NSTextView (parce que vous avez besoin de scrollview, par exemple), il vous suffit de vous lier à la propriété value au lieu de attributedString. Cette liaison utilisera le paramètre de couleur du texte du contrôle et fonctionne parfaitement avec le mode sombre.

4
Ely

Extension NSTextView pour les chaînes "simples" (non attribuées). Fonctionne en mode clair ou sombre:

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)
    }
}
1
ToddX61

Cela a fonctionné pour moi après avoir utilisé ce code (macOS Catalina version 10.15.3):

if #available(OSX 10.14, *) {         
    textView.usesAdaptiveColorMappingForDarkAppearance = true
} else {
    // Fallback on earlier versions - do nothing
}

J'ai trouvé cela documenté dans la méthode:

/ *************************** Mode sombre ******************** *******

Lorsque OUI, active le mode de mappage des couleurs adaptatif. Dans ce mode sous l'apparence effective sombre, NSTextView mappe toutes les couleurs avec NSColorTypeComponentBased en inversant la luminosité chaque fois qu'elles entrent et sortent de l'objet modèle, NSTextStorage. Par exemple, lors du rendu, de l'interaction avec NSColorPanel et NSFontManager, et de la conversion de/vers le format de table de montage et externe, les valeurs de couleur sont converties entre le modèle et les contextes de rendu. Notez que l'algorithme de conversion des couleurs comprime la plage de luminosité et, par conséquent, ne conserve pas la fidélité aller-retour entre les apparences claires et sombres. Il peut ne pas convenir à la création de texte enrichi, c'est donc une bonne idée de fournir une commande ou une préférence pour que vos utilisateurs voient et modifient leurs documents sans cette option, ou en mode léger. * /

0
Douglas Frari