2010-02-07 14 views

Antwort

29

Sie sollten Ihren Controller als Delegierter der NSTextStorage Aufgabe der NSTextView ([textView textStorage]) hinzufügen und dann die Methode delegiert implementieren ‑textStorageDidProcessEditing:. Dies wird immer dann aufgerufen, wenn sich der Text ändert.

In der Delegate-Methode müssen Sie das aktuelle Objekt NSTextStorage aus der Textansicht mit der -textStorage-Methode von NSTextView abrufen. NSTextStorage ist eine Unterklasse von NSAttributedString und enthält den zugeordneten Inhalt der Ansicht.

Ihr Code muss dann die Zeichenkette analysieren und Farbe auf alle Bereiche des Textes anwenden, die für Sie interessant sind. Sie gelten Farbe auf einen Bereich mit so etwas wie diese, die eine gelbe Farbe auf die gesamte Zeichenfolge gelten:

//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]; 

Wie Sie analysieren den Text bis zu Ihnen ist. NSScanner ist eine nützliche Klasse beim Parsen von Text.

Beachten Sie, dass diese Methode bei weitem nicht die effizienteste Methode zum Umgang mit Syntaxfärbung ist. Wenn die Dokumente, die Sie bearbeiten, sehr groß sind, werden Sie höchstwahrscheinlich in Erwägung ziehen, das Parsing auf einen separaten Thread zu verschieben und/oder clever zu sein, welche Textabschnitte repariert werden sollen.

+1

Dies ist ein bisschen alt, aber wie würde ich implementieren '-textStorageDidProcessEditing: 'in den Delegaten? – Sirens

+0

Genau wie jede andere Delegiertenmethode. Schlagen Sie die [Signatur der Methode] nach (http://developer.apple.com/library/mac/documentation/cocoa/reference/NSTextStorageDelegate_Protocol/Reference/Reference.html#//apple_ref/doc/uid/TP40008627-CH1- DontLinkElementID_3) in den Dokumenten und platzieren Sie es in der Implementierung Ihres Delegate-Objekts. Stellen Sie sicher, dass Ihr Delegatobjekt als Delegat von NSTextStorage festgelegt ist. –

+0

Danke, +1. Ihre Methode funktioniert viel besser als mein Versuch – Sirens

2

Sicher. Sie können der NSTextView eine NSAttributedString geben, und einige der Sachen, die Sie mit der attributierten Zeichenfolge tun können, ist Farben für bestimmte Teilbereiche der Zeichenfolge anwenden.

Oder Sie können search on Google und sehen, dass viele Leute damit schon einmal Sachen gemacht haben.

Ich würde wahrscheinlich empfehlen, OkudaKit zu verwenden.

+1

es scheint OkudaKit ist nicht mehr in der Entwicklung – Stephan

4

Ich empfehle Ihnen, mit dem Lesen der CocoaDev page über Syntax Highlighting zu beginnen. Viele Leute sind mit Lösungen für verschiedene Ziele gekommen.

Wenn Sie Quellcode Syntaxhervorhebung durchführen möchten, empfehle ich Ihnen, einen Blick auf die UKSyntaxColoredTextDocument von Uli Kusterer zu werfen.

+0

Lol, nie heruntergeladen so viele Proben von 1 single site, groß! –

+0

das erwähnte Tool ist jetzt auf github: [UKSyntaxColoredTextDocument] (https://github.com/uliwitness/UKSyntaxColoredTextDocument) – Stephan

9

Rob Keniger's answer ist gut, aber für jemanden auf der Suche nach einem konkreteren Beispiel, hier ist eine kurze Syntax Highlighter, schrieb ich, die RegEx-Vorlagensyntax hervorheben sollte. Ich möchte \ grau sein, mit dem Zeichen unmittelbar nach ihnen schwarz zu sein. Ich möchte $ rot sein, mit einem Ziffernzeichen unmittelbar nach $, um auch rot zu sein. Alles andere sollte schwarz sein. Hier ist meine Lösung:

ich eine Vorlage Highlighter Klasse gemacht, mit einem Header, der wie folgt aussieht:

@interface RMETemplateHighlighter : NSObject <NSTextStorageDelegate> 

@end 

ich initialisieren es in der Nib-Datei als ein Objekt und es Haken bis zu meinem View-Controller mit einem Auslauf.In awakeFromNib des View-Controllers, ich habe diese (wo replacer meine NSTextView Auslass ist und templateHighlighter ist der Auslass für die Klasse oben):

self.replacer.textStorage.delegate = self.templateHighlighter; 

Und meine Implementierung sieht wie folgt aus:

- (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++; 
     } 
    } 
} 

So Da gehts, ein voll funktionsfähiges Beispiel. Es gab ein paar Details, die mich für ~ 10 Minuten stolpern ließen, wie die Tatsache, dass du die Zeichenfolge aus textStorage nehmen musst, um auf die einzelnen Charaktere zuzugreifen ... vielleicht rettet das andere Leute ein paar Minuten.

+0

Danke, funktioniert wie angekündigt und erspart mir ziemlich viel Zeit. –

+0

Dies funktioniert hervorragend für die Syntax-Hervorhebung, aber in meinem Fall scheint auch die "contentSize" von meinem UITextView zu brechen. Genauer gesagt scheint 'contentSize' immer die Breite der UITextView x die Höhe einer einzelnen Zeile zu sein. – carloe

+0

@carloe: Das ist eine OS X-Lösung ... du nennst 'UITextView' (nicht ** NS **' TextView'), also nehme ich an, dass du mit iOS arbeitest. Es kann kleine Unterschiede zwischen den APIs geben ... Was unter OS X am besten ist, ist unter iOS möglicherweise nicht optimal. – ArtOfWarfare