在UITextView中显示HTML文本在swift 4中发生崩溃?
我使用的是被剪掉的代码 在在UITextView中显示HTML文本在swift 4中发生崩溃?,html,ios,swift,uitextview,swift4,Html,Ios,Swift,Uitextview,Swift4,我使用的是被剪掉的代码 在UITableViewCell cell.textViewMessage.attributedText = msg.htmlToAttributedString 第一次启动时没有崩溃,但在那之后,当我运行代码时出现了崩溃,之后就不再工作了 线程1:EXC\u错误访问(代码=1,地址=0x10) #编辑要在单元格中显示的HTML字符串 <p>Here\'s a short video tour. Press play to start.</p>
UITableViewCell
cell.textViewMessage.attributedText = msg.htmlToAttributedString
第一次启动时没有崩溃,但在那之后,当我运行代码时出现了崩溃,之后就不再工作了
线程1:EXC\u错误访问(代码=1,地址=0x10)
#编辑要在单元格中显示的HTML字符串
<p>Here\'s a short video tour. Press play to start.</p><br><iframe class=\"ql-video\" frameborder=\"0\" allowfullscreen=\"true\" src=\"https://www.youtube.com\"></iframe><br>
这里是一个简短的视频教程。按play开始。
#编辑1-我正在操场上尝试运行此代码,它工作正常,但现在显示错误。请参见所附图片
看起来问题在于标记,并非每个标记都能显示在uitextview中。 您可以在uiwebview中更好地显示这些标记 我认为问题在于iframe标签 要显示iFrame,请改用uiwebview或wkwebview
谢谢这是一个受回购启发的解决方案。基本上,我们删除了
iframe
标记,并将其替换为可点击的img
:
let msg = "<p>Here\'s a short video tour. Press play to start.</p><br><iframe class=\"ql-video\" frameborder=\"0\" allowfullscreen=\"true\" src=\"https://www.youtube.com/embed/wJcOvdkI7mU\"></iframe><br>"
//Let's get the video id
let range = NSRange(location: 0, length: msg.utf16.count)
let regex = try! NSRegularExpression(pattern: "((?<=(v|V)/)|(?<=be/)|(?<=(\\?|\\&)v=)|(?<=embed/))([\\w-]++)")
guard let match = regex.firstMatch(in: msg, options: [], range: range) else {
fatalError("Couldn't find the video ID")
}
let videoId: String = String(msg[Range(match.range, in: msg)!])
//Let's replace the the opening iframe tag
let regex2 = try! NSRegularExpression(pattern:
"<[\\s]*iframe[\\s]+.*src=")
let str2 = regex2.stringByReplacingMatches(in: msg, options: [], range: range, withTemplate: "<a href=")
//And then replace the closing tag
let regex3 = try! NSRegularExpression(pattern:
"><\\/iframe>")
let range2 = NSRange(location: 0, length: str2.utf16.count)
let str3 = regex3.stringByReplacingMatches(in: str2, options: [], range: range2, withTemplate: "><img src=\"https://img.youtube.com/vi/" + videoId + "/0.jpg\" alt=\"\" width=\"\(textView.frame.width)\" /></a>") // You could adjust the width and height to your liking
//Set the text of the textView
textView.attributedText = str3.htmlToAttributedString
textView.delegate = self
如果未安装youtube应用程序,则视频将在Safari中播放
结果如下:
将选项更改为:
let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html,
NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue
]
为UITextView尝试以下操作:
let string = "<h2>The bedding was hardly able to cover it.</h2>"
if !string.isEmpty{
if let htmlData = string.data(using:String.Encoding.unicode) {
do {
let attributedText = try NSAttributedString(data: htmlData, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
cell.textViewMessage.attributedText = attributedText
} catch let e as NSError {
print("Couldn't translate \(string): \(e.localizedDescription) ")
}
}
let string=“床上用品几乎无法盖住它。”
如果!string.isEmpty{
如果让htmlData=string.data(使用:string.Encoding.unicode){
做{
让attributedText=尝试NSAttributedString(数据:htmlData,选项:[NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType],DocumentAttribute:nil)
cell.textViewMessage.attributedText=attributedText
}把e当作错误来抓{
打印(“无法翻译\(字符串):\(e.localizedDescription)”)
}
}
为UILabel尝试以下操作,将html文本设置为带有html标记的UILabel:
extension String {
var withoutHtmlTags: String {
let a = self.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil)
return a.replacingOccurrences(of: "&[^;]+;", with: "", options: String.CompareOptions.regularExpression, range: nil)
}
}
let string = "<h2>The bedding was hardly able to cover it.</h2>"
textUIlabel.text = string.withoutHtmlTags
扩展字符串{
不带HtmlTags的变量:字符串{
设a=self.replacingOccurrences(of:“]+>”,with:,options:。正则表达式,范围:nil)
返回a.replacingOccurrences(of:&[^;]+;”,with:,选项:String.CompareOptions.regularExpression,范围:nil)
}
}
let string=“床上用品几乎无法盖住它。”
textuilab.text=string.without HtmlTags
此问题的原因是表视图,此错误将随机发生,并且很难再现,因为它更具体于设备内存和UI绘制过程,这可能导致在后台线程中执行该方法。在重新分配和取消分配表单元格时,表单元格可能会在深层调用此错误方法,而HTML导入器使用非线程安全的WebKit导入器,并且希望位于主线程上
如何重现此错误:使用UITest运行代码,它会更频繁地崩溃,因为单元测试会显著降低UI绘制过程的速度
解决方案:将HTML解码为字符串应该在主线程上,但在主线程的模型层中执行此操作,而不是在单元格创建过程中执行此操作。这也将使UI更加流畅
为何未在catch block中捕获崩溃:由于Objective-C异常处理基础架构使用的未处理语言异常,您的应用程序已崩溃。SWIFT就像Cocoa的N错误的漂亮包装器。SWIFT无法处理Objective-C异常,因此无法通过Objective-C代码处理异常框架中的错误不会由您的Swift错误处理程序引起。控制台中有崩溃消息吗?没有。控制台中没有崩溃消息。xcode卡在代码上,用红线剪断。@Vishal16您可以在后台调用它吗?@QuocNguyen没有,我是从主线程中的
cellForRowAtIndexPath
方法调用它的。@Vishal16似乎有人对后台线程有问题。不是你。你能提供更多的崩溃信息吗?我已经知道了,但我需要在UITextView
上执行它。你是否用
标记或视频URL来尝试它?请检查:他们使用了…我不熟悉这个标记。但是他们使用的是UIWebView
,我的问题是使用UITextView
?您的解决方案有效,但我正在寻找解决我的崩溃日志的答案。如果没有人帮助我,我将接受您的解决方案。@Vishal16从我的测试中,会出现错误消息,因为无法在UITextField
中启用javascript,这是一个UITextView
?我指的是一个textView。主要问题是我使用try-catch
块包围该代码。仍然会发生崩溃。为什么?使用Swift 5.1使NSMutableAttributedString
使用NSAttributedString.DocumentType.html
,我需要将代码运行到主队列中。DispatchQueue.main.async{如果让attributedString=try?NSAttributedString(数据:数据,选项:[.documentType:NSAttributedString.documentType.html],documentAttributes:nil){textView.attributedText=attributedString}}
let string = "<h2>The bedding was hardly able to cover it.</h2>"
if !string.isEmpty{
if let htmlData = string.data(using:String.Encoding.unicode) {
do {
let attributedText = try NSAttributedString(data: htmlData, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)
cell.textViewMessage.attributedText = attributedText
} catch let e as NSError {
print("Couldn't translate \(string): \(e.localizedDescription) ")
}
}
extension String {
var withoutHtmlTags: String {
let a = self.replacingOccurrences(of: "<[^>]+>", with: "", options: .regularExpression, range: nil)
return a.replacingOccurrences(of: "&[^;]+;", with: "", options: String.CompareOptions.regularExpression, range: nil)
}
}
let string = "<h2>The bedding was hardly able to cover it.</h2>"
textUIlabel.text = string.withoutHtmlTags