2015-11-02 3 views
1

Я хочу изменить цвет текста определенного текста в UITextView, который соответствует индексу массива. Я смог немного изменить этот answer, но, к сожалению, цвет текста каждой соответствующей фразы изменяется только один раз.UITextView изменить цвет текста определенного текста

var chordsArray = ["Cmaj", "Bbmaj7"] 
func getColoredText(textView: UITextView) -> NSMutableAttributedString { 
    let text = textView.text 
    let string:NSMutableAttributedString = NSMutableAttributedString(string: text) 
    let words:[String] = text.componentsSeparatedByString(" ") 
    for word in words { 
     if (chordsArray.contains(word)) { 
      let range:NSRange = (string.string as NSString).rangeOfString(word) 
      string.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: range) 
     } 
    } 
    chords.attributedText = string 
    return string 
} 

Результат
outcome

+0

'NSAttributedString' - ваш ответ. Используйте цветные атрибуты для части, которую вы хотите покрасить, и сделайте ее одной строкой. Положите остальную часть в строку с прописными буквами. Теперь объедините два атрибута. – NSNoob

+0

@NSNoob не хочет беспокоить вас, но не могли бы вы привести пример? Мне трудно понять, как разделить содержащийся текст и простой текст на две разные NSAttrubttedStrings. – kye

+0

Вы редактируете textView? Я вижу клавиатуру там? Итак, я предполагаю, что вы хотите покрасить текст всякий раз, когда пользователь вводит те ключевые слова, определенные в массиве аккордов? Просто заметила клавиатуру, поэтому я предполагаю, что вы действительно хотите, что я только что описал? Перекрашивание прямо на вводе данных? – NSNoob

ответ

2

К сожалению, я только что заметил ваше сообщение. Вот рабочий пример (протестировано на детской площадке):

import UIKit 


func apply (string: NSMutableAttributedString, word: String) -> NSMutableAttributedString { 
    let range = (string.string as NSString).rangeOfString(word) 
    return apply(string, word: word, range: range, last: range) 
} 

func apply (string: NSMutableAttributedString, word: String, range: NSRange, last: NSRange) -> NSMutableAttributedString { 
    if range.location != NSNotFound { 
     string.addAttribute(NSForegroundColorAttributeName, value: UIColor.redColor(), range: range) 
     let start = last.location + last.length 
     let end = string.string.characters.count - start 
     let stringRange = NSRange(location: start, length: end) 
     let newRange = (string.string as NSString).rangeOfString(word, options: [], range: stringRange) 
     apply(string, word: word, range: newRange, last: range) 
    } 
    return string 
} 

var chordsArray = ["Cmaj", "Bbmaj7"] 
var text = "Cmaj Bbmaj7 I Love Swift Cmaj Bbmaj7 Swift" 
var newText = NSMutableAttributedString(string: text) 

for word in chordsArray { 
    newText = apply(newText, word: word) 
} 

newText 
+0

Мне не удается заставить этот пример работать в Swift 2/Xcode 7 –

+0

должен работать, я ничего не делал, кроме как принимать этот код и использовать его как есть. –

3

В случае, если кто-то это нужно в быстром 4. Это то, что я получаю от моей Xcode 9 игровых площадок :).

import UIKit 
import PlaygroundSupport 
class MyViewController : UIViewController 
{ 
    override func loadView() 
    { 
     let view = UIView() 
     view.backgroundColor = .white 

     let textView = UITextView() 
     textView.frame = CGRect(x: 150, y: 200, width: 200, height: 20) 
     textView.text = "@Kam @Jam @Tam @Ham" 
     textView.textColor = .black 
     view.addSubview(textView) 
     self.view = view 

     let query = "@" 

     if let str = textView.text { 
      let text = NSMutableAttributedString(string: str) 
      var searchRange = str.startIndex..<str.endIndex 
      while let range = str.range(of: query, options: NSString.CompareOptions.caseInsensitive, range: searchRange) { 
       text.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.gray, range: NSRange(range, in: str)) 
       searchRange = range.upperBound..<searchRange.upperBound 
      } 
      textView.attributedText = text 
     } 
    } 
} 
PlaygroundPage.current.liveView = MyViewController() 

Я думаю, что для быстрой 3, вам нужно преобразовать Range (String.Index) в NSRange вручную, как это.

let start = str.distance(from: str.startIndex, to: range.lowerBound) 
let len = str.distance(from: range.lowerBound, to: range.upperBound) 
let nsrange = NSMakeRange(start, len) 
text.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.gray, range: nsrange) 
Смежные вопросы