Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
460 views
in Technique[技术] by (71.8m points)

ios - swift uitextview html image causes crash when copy image is selected after long press

I currently have a UITextView that is displaying an NSAttributedString that contains HTML data with text and images. This data is received via API so images and text are all combined into one HTML string. This is the function that parses the HTML.

let htmlData = NSString(string: myString).data(using: String.Encoding.unicode.rawValue);
let options = [NSAttributedString.DocumentReadingOptionKey.documentType:
    NSAttributedString.DocumentType.html];
do{
    let text = try NSMutableAttributedString(data: htmlData ?? Data(), options: options, documentAttributes: nil);
    text.addAttribute(NSAttributedString.Key.font, value: UIFont(name: "Arial", size: CGFloat(fontSize)) as Any, range: NSMakeRange(0, text.length));
    return text;
}
catch let error{
    print(error);
    return NSMutableAttributedString(string: myString);
}

When long pressing on the image, a menu appears with two options (1. Copy image 2. Save to Camera Roll). When I click on Copy image, the app crashes with this error message:

Terminating app due to uncaught exception 'NSInvalidArgumentException', reason: '-[_UIConcretePasteboard setImage:]: Argument is not an object of type UIImage [(null)]'

Does anyone know how to fix this so when long pressing on the image and selecting Copy image, it will not crash?


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

You need to convert images from html to NSTextAttachment, like you do it for text to NSAttributedString. And when attach these attachments to NSAttributedString.

It can look somehow like this:

let htmlData = NSString(string: myString).data(using: String.Encoding.unicode.rawValue)
let options = [NSAttributedString.DocumentReadingOptionKey.documentType:
    NSAttributedString.DocumentType.html]
let image = UIImage(named: IMAGENAME_FROM_HTML) ?? UIImage()
let imageAttachment = NSTextAttachment(image: image)

do {
    let text = try NSMutableAttributedString(data: htmlData ?? Data(), options: options, documentAttributes: nil)
    text.addAttribute(.font, value: UIFont(name: "Arial", size: CGFloat(fontSize), range: NSMakeRange(0, text.length))
    let textWithAttachment = try NSAttributedString(attachment: imageAttachment)
    text.replaceCharacters(in: NSMakeRange(RANGE_FOR_IMAGE_IN_HTML), with: textWithAttachment)
    return text
}
catch let error {
    print(error)
    return NSMutableAttributedString(string: myString)
}

P.S. don't use semicolon on the lines end in swift.


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...