Swift:在UITextView中加载样式化RTF后将字符串替换为NSTextAttachment

k7fdbhmy  于 2023-05-05  发布在  Swift
关注(0)|答案(1)|浏览(135)

在我的iOS/swift项目中,我正在使用以下代码将RTF文档加载到UITextView。RTF本身包含样式化文本,如“...blahblah [ABC.png] blah blah [DEF.png] blah...”,它被加载到UITextView中。
现在,我想将所有出现的[someImage.png]替换为实际图像NSTextAttachment。我该怎么做?
我知道在RTF文档中嵌入图像的可能性,但我不能在这个项目中这样做。

if let rtfPath = Bundle.main.url(forResource: "testABC", withExtension: "rtf") 
{
    do
    {
    //load RTF to UITextView
    let attributedStringWithRtf = try NSAttributedString(url: rtfPath, options: [.documentType: NSAttributedString.DocumentType.rtf], documentAttributes: nil)
    txtView.attributedText = attributedStringWithRtf
    
    //find all "[ABC.png]" and replace with image
    let regPattern = "\\[.*?\\]"
    //now...?
    }
}
xxls0lw8

xxls0lw81#

这里有一些你可以做的。
注意:我不是Swift开发者,更像是Objective-C开发者,所以可能会有一些丑陋的Swift代码(try!等)。但它更多的是关于使用NSRegularExpression的逻辑(我在Objective-C中使用了它,因为它在CocoaTouch中共享)
所以主线指令:
找到图像占位符的位置。
从它创建NSAttributeString/NSTextAttachment
将占位符替换为以前的属性化字符串。

let regPattern = "\\[((.*?).png)\\]"
let regex = try! NSRegularExpression.init(pattern: regPattern, options: [])

let matches = regex.matches(in: attributedStringWithRtf.string, options: [], range: NSMakeRange(0, attributedStringWithRtf.length))
for aMatch in matches.reversed()
{
    let allRangeToReplace = attributedStringWithRtf.attributedSubstring(from: aMatch.range(at: 0)).string
    let imageNameWithExtension = attributedStringWithRtf.attributedSubstring(from: aMatch.range(at: 1)).string
    let imageNameWithoutExtension = attributedStringWithRtf.attributedSubstring(from: aMatch.range(at: 2)).string
    print("allRangeToReplace: \(allRangeToReplace)")
    print("imageNameWithExtension: \(imageNameWithExtension)")
    print("imageNameWithoutExtension: \(imageNameWithoutExtension)")

    //Create your NSAttributedString with NSTextAttachment here
    let myImageAttribute = ...
    attributedStringWithRtf.replaceCharacters(in: imageNameRange, with: myImageAttributeString)
}

你的想法是什么?
我用了一种修饰模式。我硬写的“png”,但你可以改变它。我添加了一些()来轻松获得有趣的部分。我想你可能想检索图像的名称,有或没有.png,这就是为什么我得到了所有这些print()。也许是因为你把它保存在你的应用程序中,等等。如果需要将扩展作为一个组添加,您可能希望将其添加到regPattern的括号中,并检查要调用的aMatch.range(at: ??)。使用Bundle.main.url(forResource: imageName, withExtension: imageExtension)
我使用matches.reversed()是因为如果你用不同长度的替换来修改“match”的长度,那么之前的范围将被关闭。所以从最后开始就可以了。
一些代码将UIImage通过NSTextAttachment转换为NSAttributedStringHow to add images as text attachment in Swift using nsattributedstring

相关问题