2016-11-04 1 views
0

Я работаю над приложением macOS. Мне нужно выделить синтаксический текст, который помещается поверх TextView (NSTextView) со списком выбранных слов. Для простоты я фактически тестирую ту же функцию на iPhone Simulator. Во всяком случае, список слов, которые нужно выделить, является формой массива. Следующее - это то, что у меня есть.Текст с подсветкой синтаксиса с пользовательским списком ключевых слов

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 \ Nlet. Если я отделяю любое слово, содержащее \ n, с быстрым перечислением, код не будет хорошо обнаруживать каждый новый абзац. Я ценю любые советы, чтобы сделать его лучше. Просто FYI, я собираюсь оставить эту тему открытой как для 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.» –

 Смежные вопросы

  • Нет связанных вопросов^_^