Je travaille sur un éditeur de texte Cocoa qui utilise un NSTextView. Est-il possible de changer la couleur de certaines parties du texte?Surlignement de la syntaxe NSTextView
Répondre
Vous devez ajouter votre contrôleur en tant que délégué de l'objet NSTextStorage
du NSTextView
([textView textStorage]
), puis implémenter la méthode de délégation ‑textStorageDidProcessEditing:
. Ceci est appelé chaque fois que le texte change.
Dans la méthode déléguée, vous devez obtenir l'objet NSTextStorage
actuel à partir de la vue de texte à l'aide de la méthode -textStorage
de NSTextView
. NSTextStorage
est une sous-classe de NSAttributedString
et contient le contenu attribué de la vue.
Votre code doit ensuite analyser la chaîne et appliquer une coloration à toutes les plages de texte qui vous intéressent. Vous appliquez la couleur à une plage en utilisant quelque chose comme ça, qui applique une couleur jaune à la chaîne entière:
//get the range of the entire run of text
NSRange area = NSMakeRange(0, [textStorage length]);
//remove existing coloring
[textStorage removeAttribute:NSForegroundColorAttributeName range:area];
//add new coloring
[textStorage addAttribute:NSForegroundColorAttributeName
value:[NSColor yellowColor]
range:area];
Comment vous analysez le texte est à vous. NSScanner
est une classe utile à utiliser lors de l'analyse du texte. Notez que cette méthode n'est en aucun cas la manière la plus efficace de gérer la coloration de la syntaxe.
Si les documents que vous éditez sont très volumineux, vous voudrez probablement envisager de décharger l'analyse dans un fil séparé et/ou d'être astucieux sur les sections de texte réparées.
Bien sûr. Vous pouvez donner à la NSTextView
une NSAttributedString
, et certaines des choses que vous pouvez faire avec la chaîne attribuée sont appliquer des couleurs à certaines sous-chaînes de la chaîne.
Ou vous pouvez search on Google et voir que beaucoup de gens ont fait des choses avec cela avant.
Je recommanderais probablement d'utiliser OkudaKit.
il semble OkudaKit n'est plus en développement – Stephan
Je vous recommande de commencer par lire le CocoaDev page à propos de Syntax Highlighing. Beaucoup de gens sont venus avec des solutions pour divers objectifs.
Si vous souhaitez mettre en surbrillance la syntaxe du code source, je vous suggère de regarder le UKSyntaxColoredTextDocument de Uli Kusterer.
Lol, jamais téléchargé autant d'échantillons à partir de 1 site unique, génial! –
l'outil mentionné est maintenant sur github: [UKSyntaxColoredTextDocument] (https://github.com/uliwitness/UKSyntaxColoredTextDocument) – Stephan
Rob Keniger's answer est bon, mais pour quelqu'un qui cherche un exemple plus concret, voici une petite syntaxe surlignée que j'ai écrit qui devrait mettre en évidence la syntaxe du modèle RegEx. Je veux que \
soit gris, avec le personnage qui les suit immédiatement pour être noir. Je veux que $
soit rouge, avec un caractère immédiatement après le $
pour être également rouge. Tout le reste devrait être noir. Voici ma solution:
J'ai fait une classe surligneur de modèle, avec un en-tête qui ressemble à ceci:
@interface RMETemplateHighlighter : NSObject <NSTextStorageDelegate>
@end
J'initialize dans le fichier nib comme un objet et de le raccorder à mon contrôleur de vue avec un sortie.En awakeFromNib
du contrôleur de vue, j'ai ce (où replacer
est mon exutoire NSTextView
et templateHighlighter
est la sortie de la classe ci-dessus):
self.replacer.textStorage.delegate = self.templateHighlighter;
Et mon implémentation ressemble à ceci:
- (void)textStorageDidProcessEditing:(NSNotification *)notification {
NSTextStorage *textStorage = notification.object;
NSString *string = textStorage.string;
NSUInteger n = string.length;
[textStorage removeAttribute:NSForegroundColorAttributeName range:NSMakeRange(0, n)];
for (NSUInteger i = 0; i < n; i++) {
unichar c = [string characterAtIndex:i];
if (c == '\\') {
[textStorage addAttribute:NSForegroundColorAttributeName value:[NSColor lightGrayColor] range:NSMakeRange(i, 1)];
i++;
} else if (c == '$') {
NSUInteger l = ((i < n - 1) && isdigit([string characterAtIndex:i+1])) ? 2 : 1;
[textStorage addAttribute:NSForegroundColorAttributeName value:[NSColor redColor] range:NSMakeRange(i, l)];
i++;
}
}
}
Alors là vous allez, un exemple pleinement fonctionnel. Il y avait quelques détails qui m'ont fait trébucher pendant ~ 10 minutes, comme le fait que vous devez sortir la chaîne de textStorage pour accéder aux caractères individuels ... peut-être que cela sauvera d'autres personnes quelques minutes.
Merci, fonctionne comme annoncé et m'a sauvé un certain temps. –
Cela fonctionne très bien pour la mise en évidence de la syntaxe, mais dans mon cas, semble également casser le 'contentSize' de mon UITextView. Plus précisément, 'contentSize' semble toujours être la largeur de UITextView x la hauteur d'une seule ligne. – carloe
@carloe: Ceci est une solution OS X ... vous mentionnez 'UITextView' (pas ** NS **' TextView') donc je suppose que vous travaillez avec iOS. Il peut y avoir de petites différences entre les API ... ce qui est le mieux sur OS X n'est peut-être pas le meilleur sur iOS. – ArtOfWarfare
Ceci est un peu vieux, mais comment j'implémenterais '-textStorageDidProcessEditing:' dans le délégué? – Sirens
Comme toute autre méthode de délégué. Recherchez la [signature de la méthode] (http://developer.apple.com/library/mac/documentation/cocoa/reference/NSTextStorageDelegate_Protocol/Reference/Reference.html#//apple_ref/doc/uid/TP40008627-CH1- DontLinkElementID_3) dans les documents et placez-le dans l'implémentation de votre objet délégué. Assurez-vous que votre objet délégué est défini en tant que délégué de 'NSTextStorage'. –
Merci, +1. Votre méthode fonctionne beaucoup mieux que ma tentative – Sirens