我正在使用具有自定义支持UITextView
的可编辑NSTextStorage
。
用户正在通过正则表达式匹配和属性替换来编辑在自定义NSTextStorage
内设置样式的纯文本,
我想添加内联图像,以便当用户键入图像名称(实际上是图像的降价链接)时,我会在用户键入的链接后添加图像。
要实现此目的,我只需使用包含要显示的NSAttributedString
的{{1}}创建一个新的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
的新字符,从而使可编辑字符串和后备内容不同步。
有什么更好的方法?我希望用户仅使用纯文本的原始(降价)字符串。其余所有内容都应该是渲染器的一部分,甚至不可编辑。该图像应该在那里,用户可以点击它以在另一视图中实际重绘它,但是他甚至不能用退格键将其删除。如果实际的降价链接无效,则应将其删除。