J'utilise ce code coupé
var htmlToAttributedString: NSAttributedString? {
guard let data = data(using: .utf8) else { return NSAttributedString() }
do {
return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil) // Get crash on this line
} catch let error {
print(error.localizedDescription)
return NSAttributedString()
}
}
var htmlToString: String {
return htmlToAttributedString?.string ?? ""
}
affichage de HTML
texte dans UITableViewCell
cell.textViewMessage.attributedText = msg.htmlToAttributedString
En lançant la première fois, il n'y a pas de crash, mais après cela, lorsque je lance le code, un crash se produit et ne fonctionne plus.
Fil 1: EXC_BAD_ACCESS (code = 1, adresse = 0x10)
#Edit HTML Chaîne à afficher dans la cellule
<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>
#Edit 1 - J'essaie d'exécuter ce code dans Playground et tout fonctionne correctement, sauf que maintenant, une erreur est affichée. S'il vous plaît voir l'image ci-jointe
On dirait que le problème est la balise, toutes les balises ne peuvent pas apparaître dans uitextview. Vous pouvez mieux afficher ces balises dans uiwebview
Je pense que le problème est iframe tag.
Pour afficher iFrame, utilisez plutôt uiwebview ou wkwebview.
Merci
Voici une solution inspirée par this repo. Fondamentalement, nous supprimons la balise iframe
et la remplaçons par la img
cliquable:
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
Pour ouvrir l'application Youtube lorsque l'utilisateur appuie de manière prolongée sur l'image, implémentez cette méthode de délégué:
extension NameOfYourViewController: UITextViewDelegate {
func textView(_ textView: UITextView, shouldInteractWith URL: URL, in characterRange: NSRange, interaction: UITextItemInteraction) -> Bool {
UIApplication.shared.open(URL, options: [:])
return true
}
}
Si l'application youtube n'est pas installée, la vidéo sera lue dans Safari.
Voici le résultat:
Essayez ceci pour 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) ")
}
}
Essayez ceci pour UILabel pour la définition de texte HTML sur Uilabel avec des balises HTML:
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
Change vos options pour:
let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html,
NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue
]