2016-11-04 54 views
0

我正在開發一個macOS應用程序。我需要使用選定單詞列表的語法突出顯示置於TextView(NSTextView)上的文本。爲了簡單起見,我實際上正在iPhone模擬器上測試相同的功能。無論如何,要突出顯示的單詞列表以數組的形式出現。以下是我的。使用自定義關鍵字列表語法高亮顯示文本

func HighlightText { 
    let tagArray = ["let","var","case"] 
    let style = NSParagraphStyle.defaultParagraphStyle().mutableCopy() as! NSMutableParagraphStyle 
    style.alignment = NSTextAlignment.Left 
    let words = textView.string!.componentsSeparatedByString(" ") // textView.text (UITextView) or textView.string (NSTextView) 
    let attStr = NSMutableAttributedString() 
    for i in 0..<words.count { 
     let word = words[i] 
     if HasElements.containsElements(tagArray,text: word,ignore: true) { 
      let attr = [ 
       NSForegroundColorAttributeName: syntaxcolor, 
       NSParagraphStyleAttributeName: style, 
       ] 
      let str = (i != words.count-1) ? NSAttributedString(string: word.stringByAppendingString(" "), attributes: attr) : NSAttributedString(string: word, attributes: attr) 
      attStr.appendAttributedString(str) 
     } else { 
      let attr = [ 
       NSForegroundColorAttributeName: NSColor.blackColor(), 
       NSParagraphStyleAttributeName: style, 
       ] 
      let str = (i != words.count-1) ? NSAttributedString(string: word.stringByAppendingString(" "), attributes: attr) : NSAttributedString(string: word, attributes: attr) 
      attStr.appendAttributedString(str) 
     } 
    } 
    textView.textStorage?.setAttributedString(attStr) 
} 

class HasElements { 
    static func containsElements(array:Array<String>,text:String,ignore:Bool) -> Bool { 
     var has = false 
     for str in array { 
      if str == text { 
        has = true 
       } 
     } 
     return has 
    } 
} 

這裏的簡單方法是將整個字符串用空白(「」)分隔成單詞,並將每個單詞放入一個數組(單詞)中。 containsElements函數只是告訴所選單詞是否包含數組中的一個關鍵字(tagArray)。如果它返回true,那麼這個單詞被放在一個帶有高亮顏色的NSMutableAttributedString中。否則,它會被放在與純色相同的屬性字符串中。

這個簡單的方法的問題是,一個單獨的詞將最後一個單詞和/ n和下一個單詞放在一起。舉例來說,如果我有一個像

let base = 3 
let power = 10 
var answer = 1 

一個字符串,僅第一個「讓」的代碼把3和下讓在一起,就像將突出「3 \ n別忘了。」如果我用快速枚舉分隔包含\ n的任何單詞,代碼將無法很好地檢測每個新段落。我很欣賞任何建議,使其更好。僅供參考,我將把這個主題留給macOS和iOS。

Muchos thankos

回答

1

情侶不同的選擇。字符串有一個名爲componentsSeparatedByCharactersInSet的函數,它允許您通過您定義的字符集進行分隔。不幸的是,這是行不通的,因爲你想分開\n這是一個以上的字符。

您可以將單詞分割兩次。 。

let firstSplit = textView.text!.componentsSeparatedByString(" ") 
var words = [String]() 
for word in firstSplit { 
    let secondSplit = word.componentsSeparatedByString("\n") 
    words.appendContentsOf(secondSplit) 
} 

但你不會有換行符的任何意義..你就需要重新添加它們放回

最後,最簡單的黑客很簡單:

let newString = textView.text!.stringByReplacingOccurrencesOfString("\n", withString: "\n ") 
let words = newString.componentsSeparatedByString(" ") 

所以基本上你添加自己的空間。

+0

謝謝。除了第一個以外的所有行都以空格開頭,這種方式稍微好一些。所以第二行是'let power = 10',第三行是'var answer = 1'。 –

相關問題