Я работаю с редактируемым UITextView
, имеющим пользовательскую подложку NSTextStorage
.
. Пользователь редактирует простой текст, стилизованный внутри пользовательского NSTextStorage
, с помощью соответствия регулярному выражению и заменяетатрибуты, и это работает как шарм.
Я хотел добавить встроенные изображения, чтобы, когда пользователь вводит имя изображения (на самом деле ссылка на изображение вниз), я добавляю изображение сразу после ссылки, котораяпользователь набрал.
Для этого я просто создаю новый NSAttributedString
с NSTextAttachment
, содержащим UIImage
, который я хочу отобразить.
Вот фактический код:
func applyImages(_ range: NSRange) {
guard let bounds = self.bounds else { return }
let backingString = backingStore.string
let regex = "\\!\\[([^\\]]+)\\]\\(([^\\)\"\\s]+)(?:\\s+\"(.*)\")?\\)".toRegex()
regex.enumerateMatches(in: backingString, options: .withoutAnchoringBounds, range: range, using: { (match, flags, stop) in
guard let match = match else { return }
let attachment = NSTextAttachment()
attachment.image = UIImage.init(named: "1.png")
attachment.bounds = CGRect.init(x: 0, y: 0, width: bounds.width, height: 100)
let img = NSMutableAttributedString.init(attachment: attachment)
let imgRange = NSRange.init(location: match.range(at: 0).location + match.range(at: 0).length, length: img.length)
self.beginEditing()
if !backingStore.containsAttachments(in: imgRange) {
backingStore.insert(img, at: match.range(at: 0).location + match.range(at: 0).length)
self.edited([.editedCharacters, .editedAttributes], range: range, changeInLength: img.length)
} else {
backingStore.replaceCharacters(in: imgRange, with: img)
self.edited([.editedCharacters, .editedAttributes], range: range, changeInLength: 0)
}
self.endEditing()
})
}
backingString
является экземпляром NSTextStorage
.
Проблема этого подхода заключается в том, что я добавляю новый символ, который содержит NSTextAttachment
в исходной строке, таким образом делаяредактируемая строка и вспомогательное содержимое не синхронизированы.
Что может быть лучше?Я хочу, чтобы пользователь просто работал с исходной (уценкой) строкой, которая представляет собой просто текст.Все остальное должно быть частью рендера и даже не редактироваться.Изображение должно быть там, и пользователь может нажать на него, чтобы фактически перерисовать его в другом виде, но он даже не сможет удалить его с помощью возврата.Его следует удалить, если действительная ссылка на скидку недействительна.