【发布时间】:2016-11-04 11:38:25
【问题描述】:
我正在开发一个 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
,只有第一个 'let' 会突出显示,因为代码将 3 和下一个 let 放在一起,如 '3\nlet'。如果我用快速枚举分隔任何包含 \n 的单词,则代码将无法很好地检测每个新段落。我很感激任何建议,让它变得更好。仅供参考,我将把这个话题对 macOS 和 iOS 开放。
非常感谢
【问题讨论】:
标签: ios swift macos syntax-highlighting