2017-02-01 2 views
0

У меня есть UITextView, который позволяет выбирать слова текста, нажимая его. Если оно постукивается, слово выделяется цветом, изменяя атрибут NSForegroundColor. Повторное нажатие на него отменяет его, меняя цвет на цвет текста.Получить цвет измененных слов атрибутивной строки

Теперь мне нужно будет знать все выбранные слова в UITextView.

Первой идеей было удалить все, что является особым символом, и разделить текст в пространстве. Затем проверьте, соответствует ли атрибут цвета выбранному/выделенному цвету каждого отдельного слова. Но атрибутная строка не позволяет разбивать на символ или удалять компоненты. Также нет NSAttributedString.

Вторая идея состояла в том, чтобы сохранить диапазоны выделенных частей в массиве и перебрать их, чтобы получить выделенные части. Но для меня это кажется слишком сложным, тем более, что мне нужен правильный порядок слов по мере их появления, который не гарантируется с помощью массива, добавьте/удалите на каждом касании (Например, скажем, текст: «Это тест»

Tap this -> index 0 
Tap test -> index 1 
Tap this -> test becomes index 0 
Tap this -> this becomes index 1 

то порядок не уедет.

Я уже понял, как получить цвет в приписываемой строке. это не проблема.

Как я могу перебрать связанная строка и выяснить слова, которые изменили цвет или что является наилучшим способом решения этой проблемы?

Спасибо!

Привет

ответ

2

Вы можете перебрать приписанного строку ищет атрибут цвета.

Последующий код показывает, как:

// This generates a test attributed string. 
// You actually want the attributedText property of your text view 
let str = NSMutableAttributedString(string: "This is a test of the following code") 
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(0, 4)) 
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(8, 1)) 
str.addAttributes([NSForegroundColorAttributeName:UIColor.red], range: NSMakeRange(15, 2)) 
print(str) 

Вышеприведенные напечатает:

This{ 
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1"; 
} is { 
}a{ 
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1"; 
} test { 
}of{ 
    NSColor = "UIExtendedSRGBColorSpace 1 0 0 1"; 
} the following code{ 
} 

Этот код обрабатывает приписываемое строку. Любой диапазон текста, форматированный с передним цветом, будет помещен в массив слов.

var words = [String]() 
str.enumerateAttribute(NSForegroundColorAttributeName, in: NSMakeRange(0, str.length), options: []) { (value, range, stop) in 
    if value != nil { 
     let word = str.attributedSubstring(from: range).string 
     words.append(word) 
    } 
} 
print(words) 

Печатается:

[ "Это", "а", "о"]

+0

Спасибо, работает как шарм! –

0

Я могу предложить вам создать своего рода хранилище для выбранных диапазонов, а затем на основе этого диапазона вы можете настроить внешний вид этого слова, а не другим способом. Это позволит вам получать доступ к выбранным словам каждый раз, не проверяя атрибуты всего текста.

+0

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

0

Хотя я согласен с Piotr, что вы должны хранить Ranges, чтобы ответить на ваш вопрос:

attributedString.enumerateAttributes(in: NSMakeRange(0, attributedString.length), options: []) { attributes, range, _ in 
    if let color = attributes[NSForegroundColorAttributeName] as? UIColor, 
     color == YOUR_HIGHLIGHT_COLOR { 
     let nString = attributedString.string as NSString 
     let word = nString.substring(with: range) 
     // Do what you want with the word 
    } 
} 
Смежные вопросы