web-dev-qa-db-fra.com

L'affichage de texte HTML dans une collision UITextView s'est produit dans Swift 4?

J'utilise ce code coupé

 Code to show HTML Text in TextView

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

 Playground output

7
Vishal16

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

5
antonio yaphiar

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:

 Youtube in a UITextField

1
Carpsen90

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
0
Mahesh Shahane

Change vos options pour:

let options: [NSAttributedString.DocumentReadingOptionKey: Any] = [
                NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html,
                NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue
            ]
0
Honey