
Раньше мне было сложно понять, как работать с «#» и «@», но я, наконец, нашел хороший метод работы.
Установка
Во-первых, это лучше всего работает в TextView. Поэтому настройте его внутри вашего представления, как хотите, но убедитесь, что ваш ViewController имеет UITextViewDelegate, а textView делегирован этому контроллеру представления.
Я также делаю это с некоторой предварительно заполненной информацией, но та же концепция применима к извлечению данных из вашей базы данных и тому подобное.

[Ради учебника я настроил свой textView с помощью раскадровки. Быстро и просто. Не трогай меня.]
Вот как мы настраиваем наш ViewController:
class ViewController: UIViewController, UITextViewDelegate {
var string = "Hello, my name is @Jared & #Jared and I like to move it."
@IBOutlet weak var textView: UITextView!
override func viewDidLoad() {
super.viewDidLoad()
textView.text = string
textView.delegate = self
}
...
Разрешение символов
Теперь мы переходим к самым серьезным вещам! (Ву!)

Общая задача, которую мы пытаемся решить в этой части, - просто разделить все слова в нашем textView. Это проще, чем вы думаете:
Во-первых, давайте создадим наше расширение:
extension UITextView {
func resolveTags(){
[Забегая вперед, это просто добавление материала в функцию resolveTags, пока я не укажу обратное]
Преобразуйте нашу строку в NSString. Это позволяет разделить компоненты.
let nsText:NSString = self.text as NSString
Разделите слова, используя .compenents (separatedBy: ««) ‹- Включите этот пробел в кавычки. Это позволит нам разделить отдельные слова.
let words:[String] = nsText.components(separatedBy: " ")
Настройте пару атрибутов для того, как вы хотите, чтобы ваш текст выглядел в TextView. Эти атрибуты будут применены к любому TextView, для которого вы вызываете resolveTags, поэтому сделайте:
let attrs = [
NSAttributedStringKey.font : UIFont.init(name: "HelveticaNeue", size: 13),
NSAttributedStringKey.foregroundColor : UIColor.black
]
После создания этих атрибутов нам теперь нужно передать их и наш nsText в NSMutableAttributedString. Это позволит нам добавить крутые синие блики и сделать его интерактивным.
let attrString = NSMutableAttributedString(string: nsText as String, attributes:attrs)
Затем мы перебираем слова и проверяем префиксы. Сначала мы будем работать только с "#"
for word in words {
if word.hasPrefix("#") {
Затем нам нужно получить диапазон символов, который мы хотим добавить для нашей кликабельности:
let matchRange:NSRange = nsText.range(of: word as String)
Затем мы преобразуем наше слово в String, а не в NSString. Это позволит нам отбросить «#» в начале нашего значения. Таким образом, вместо того, чтобы получать @jared при нажатии, вы фактически получаете просто «jared».
var stringifiedWord:String = word as String stringifiedWord = String(stringifiedWord.dropFirst())
Затем мы добавляем пару атрибутов в нашу attrString. Здесь мы просто добавляем ссылку и ее диапазон. Убедитесь, что ваше значение установлено на «hash: \ (stringifiedWord)». Наличие этого «хеша» впереди позволит нам позже возиться с вещами, когда мы сделаем его кликабельным.
attrString.addAttribute(NSAttributedStringKey.link, value: "hash:\(stringifiedWord)", range: matchRange)
Наконец, мы придаем ему сладкий, сладко-голубой цвет. 👌
attrString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.blue , range: matchRange)
Теперь мы делаем то же самое для нашего символа «@».
} else if word.hasPrefix("@") {
let matchRange:NSRange = nsText.range(of: word as String)
var stringifiedWord:String = word as String
stringifiedWord = String(stringifiedWord.dropFirst())
attrString.addAttribute(NSAttributedStringKey.link, value: "user:\(stringifiedWord)", range: matchRange)
attrString.addAttribute(NSAttributedStringKey.foregroundColor, value: UIColor.blue , range: matchRange)
}
Наконец, ОЧЕНЬ важный шаг, мы применяем нашу attrString к нашему textView. 💪
self.attributedText = attrString } // Close up your resolveTags function.
Давай воспользуемся этой штукой!
Все сводится к этому. У нас есть эта функция, как теперь ее использовать?
Легкий.
Внутри вашей функции viewDidLoad или где бы вы ни установили текст textView, просто вызовите:
textView.resolveTags()

Это дает вам такой результат ... НО вы пока не можете нажимать на эти элементы. Почему?!
Перестань беспокоиться.
Все, что нам нужно сделать, это добавить эту функцию:
func textView(_ textView: UITextView, shouldInteractWith touchedURL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
Если вы - делегат textView, настроенный для вашего ViewController, как я уже говорил вам ранее (что вы следовали идеально… верно?), Эта функция будет вызываться при нажатии одного из этих выделенных слов. Теперь давайте добавим сюда логику для обработки этих нажатий:
if touchedURL.absoluteString.contains("hash:") {
print("HASHTAG") // This is where you move onto another view or do something mind-blowing.
}
else if touchedURL.absoluteString.contains("user:") {
print("USER") // This is where you move onto another view or do something mind-blowing.
}
return true
Если у вас возникли проблемы с нажатием на текст, попробуйте включить isSelectable и выключить isEditable.
Вот и все!
Теперь ты можешь веселиться, как будто завтра не наступит, мой друг, потому что теперь у тебя все работает. Если это помогло и вы чувствуете себя щедрым, поддержите мои усилия! :]