2010-02-07 215 views

回答

29

您應該添加您的控制器的NSTextView[textView textStorage])的NSTextStorage對象的委託,然後實現委託方法‑textStorageDidProcessEditing:。這在文本更改時被調用。

在委託方法中,您需要使用-textStorage方法NSTextView從文本視圖中獲取當前的NSTextStorage對象。 NSTextStorageNSAttributedString的一個子類,包含視圖的屬性內容。

您的代碼必須解析字符串並將着色應用到您感興趣的任何文本範圍。應用顏色的使用範圍這樣的事情,這將採用黃色整個字符串:

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

你如何分析文本是由你。在解析文本時使用NSScanner是一個有用的類。

請注意,此方法絕不是處理語法着色的最有效方式。如果您正在編輯的文檔非常大,您很可能會考慮將分析卸載到單獨的線索和/或靈巧地重新分類文本的哪些部分。

+1

這有點舊了,但是如何實現'-textStorageDidProcessEditing:'到代理中? – Sirens 2012-07-23 15:53:57

+0

就像任何其他代表方法一樣。查找[方法的簽名](http://developer.apple.com/library/mac/documentation/cocoa/reference/NSTextStorageDelegate_Protocol/Reference/Reference.html#//apple_ref/doc/uid/TP40008627-CH1- DontLinkElementID_3)並將其放置在您的委託對象的實現中。確保你的委託對象被設置爲'NSTextStorage'的委託。 – 2012-07-23 22:07:05

+0

謝謝,+1。你的方法比我的嘗試更有效 – Sirens 2012-07-24 02:37:23

2

當然。你可以給NSTextView一個NSAttributedString,你可以用屬性字符串做的一些事情是將顏色應用到字符串的某些子範圍。

或者你可以search on Google看到很多人以前用過這個東西。

我可能會推薦使用OkudaKit

+1

它似乎OkudaKit不再在開發 – Stephan 2012-12-12 05:47:43

4

我建議你通過閱讀CocoaDev page有關語法Highlighing啓動。很多人都有針對不同目標的解決方案。

如果您想要執行源代碼語法高亮顯示,我建議您查看Uli KustererUKSyntaxColoredTextDocument

+0

大聲笑,從來沒有從1個單一網站下載這麼多樣本,太棒了! – 2011-07-26 20:01:56

+0

提到的工具現在在github上:[UKSyntaxColoredTextDocument](https://github.com/uliwitness/UKSyntaxColoredTextDocument) – Stephan 2012-12-12 05:54:47

9

Rob Keniger's answer是好的,但對於某人來說找一個更具體的例子,這裏是一個簡短的語法高亮顯示我寫的應該突出的正則表達式的模板語法。我想\是灰色的,隨着字符緊跟着它們變成黑色。我想$是紅色的,緊接在$之後的數字字符也是紅色的。其他一切應該是黑色的。這裏是我的解決方案:

我做了一個模板熒光筆類,它有一個頭,看起來像這樣:

@interface RMETemplateHighlighter : NSObject <NSTextStorageDelegate> 

@end 

我初始化它的筆尖文件作爲一個對象,並把它掛到我的一個視圖控制器出口。在視圖控制器的awakeFromNib,我有這個(其中replacer是我NSTextView出口和​​是上述類出口):

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

,我的實是這樣的:

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

所以你去了,一個充分運作的例子。有幾個細節讓我絆倒了大約10分鐘,比如你必須從textStorage中取出字符串才能訪問各個角色...也許這會在幾分鐘內保存其他人。

+0

謝謝,作品廣告和保存我相當一段時間。 – 2014-05-09 18:19:33

+0

這對於語法高亮顯得很好,但在我的情況下,似乎也打破了我的UITextView的'contentSize'。更具體地說,'contentSize'似乎總是UITextView的寬度x單行高度。 – carloe 2015-05-07 11:53:43

+0

@carloe:這是一個OS X解決方案...你提到'UITextView'(不是NS **'TextView'),所以我假設你正在使用iOS。這些API之間可能存在細微差異...... OS X上最好的版本在iOS上可能不是最好的。 – ArtOfWarfare 2015-05-07 14:34:33