Цель состоит в том, чтобы сделать URL-адреса голубыми в реальном времени, когда пользователи вводят UITextView
, аналогично тому, как работает Twitter при составлении твитов.
В приведенном ниже коде показан один из вариантов: используйте NSDataDetector
дляобнаружить ссылки внутри textViewDidChange(textView:)
.Это позволяет вам определять, когда кто-то добавляет / удаляет символы для формирования / разрыва строк URL, и также обрабатывает, когда кто-то вставляет блок текста.Но производительность ужасна, так как вы проверяете весь текст на каждой набранной букве.
Обнаружение внутри textView:shouldChangeTextInRange:replacementText:
кажется многообещающим, потому что вы изучаете только замещающий текст.Тем не менее, это кажется хакерским, поскольку кажется, что цель функции - предоставить / запретить разрешение редактировать текст, а не изменять что-либо.
В идеале, была бы более подходящая функция для изменения замещающего текста, ноПохоже, не один.
Как лучше всего окрашивать URL-адреса в режиме реального времени в UITextView?
// Exit if no attributed text
guard let attributedText = textView.attributedText else {
return
}
// Get mutuable attributed text
let mutableAttributedText = NSMutableAttributedString(attributedString: attributedText)
// Detect and linkify URLs in text
do {
// Set detector
let types: NSTextCheckingResult.CheckingType = [.link]
let detector = try NSDataDetector(types: types.rawValue)
let detectorRange = NSMakeRange(0, textView.text.count)
// Iterate over matches
detector.enumerateMatches(in: textView.text, options: [], range: detectorRange) { result, _, _ in
// Found detector result?
if let result = result {
// Linkify text if it contains URL
if result.resultType == .link {
// Set link attributes
let urlString = mutableAttributedText.attributedSubstring(from: result.range)
let linkAttributes: [NSAttributedString.Key: Any] = [
.foregroundColor: curLinkColor,
NSAttributedString.Key.link: urlString
]
// Update <mutableAttributedText>
mutableAttributedText.addAttributes(linkAttributes, range: result.range)
// Print status
print("Converted link: \(urlString). Detector result: \(result).")
}
}
}
} catch {
printError("Error detecting types in text view: \(error).")
}