web-dev-qa-db-fra.com

Format HTML dans UITextView

je suis assez nouveau pour le développement iOS et je travaille actuellement sur une application qui reçoit une sorte de données JSON. Mais certains experts du backend ont pensé qu'il serait préférable pour l'utilisateur de simplement copier les informations directement à partir de Word et de les coller dans le système d'information. Donc, je suis assis ici, essayant de faire un lien cliquable dans un UITableView.

J'analyse les données de Web et obtient une chaîne avec ce format:

F&uuml;r mehr Informationen klicken sie <a href="http://www.samplelink.com/subpage.php?id=8">here</a>.

J'ai déjà essayé un UILabel, mais après quelques recherches, j'utilise maintenant le fréquemment suggéré UITextView. Dans l'inspecteur d'attributs, je le définit comme un texte d'attribut et active la détection de lien. Maintenant, le texte est affiché en rouge et est cliquable. 

Le problème maintenant pour moi est que les balises HTML et le jeu de caractères correct (allemand) sont toujours manquants et je ne sais pas comment les afficher de la bonne manière.

La chaîne montrée est analysée de cette façon:

    func showHTMLString(unformattedString: String) -> NSAttributedString{
    var attrStr = NSAttributedString(
        data: tmpString.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true)!,
        options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
        documentAttributes: nil,
        error: nil)
    return attrStr!
}

Si je remplis le Textview avec attrStr?.string, le format est affiché correctement mais le lien a également disparu.

Des suggestions sur la manière de formater la chaîne montrée de la bonne manière?

Merci d'avance AR4G4

10
a2hur

Le problème est que vous devez modifier les options de codage de caractères de NSUnicodeStringEncoding à NSUTF8StringEncoding pour charger votre code html de la manière appropriée. Je pense que vous devriez créer une propriété calculée en lecture seule avec l'extension de chaîne pour convertir votre code html en chaîne attribuée:

Xcode 8.3.1 • Swift 3.1

extension Data {
    var attributedString: NSAttributedString? {
        do {
            return try NSAttributedString(data: self, options:[NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue], documentAttributes: nil)
        } catch {
            print(error)
        }
        return nil
    }
}
extension String {
    var data: Data {
        return Data(utf8)
    }
}

let htmlStringCode = "F&uuml;r mehr Informationen klicken sie <a href=\"http://www.samplelink.com/subpage.php?id=8\">here</a>"

htmlStringCode.data.attributedString?.string ?? ""  // "Für mehr Informationen klicken sie here"

dans ton cas

yourTextView.attributedText = htmlStringCode.data.attributedString
26
Leo Dabus

Vérifiez les attributs de votre UITextView dans IB. Pour que les liens fonctionnent, vous devez avoir coché Selectable.

enter image description here

2
fred02138

Je recommanderais l'affichage de HTML dans une UIWebView. Il est plus robuste que d’utiliser une variable UITextView. Voir Afficher le texte HTML dans uitextview pour plus d'informations.

1
tng

J'ai utilisé le code pour Swift 4:

var descriptionStr : String = String() //Dynamic text

let regex = try! NSRegularExpression(pattern: "<.*?>", options: [.caseInsensitive])
        let range = NSRange(location: 0, length: descriptionStr.count)
        let htmlLessString: String = regex.stringByReplacingMatches(in: descriptionStr, options: NSRegularExpression.MatchingOptions(), range:range, withTemplate: "")
        textViewRef.text = htmlLessString
1
Mannam Brahmam

J'avais une application qui avait une UITextView dans laquelle je voulais pouvoir coller du texte formaté HTML à partir du navigateur, puis l'enregistrer en tant que chaîne (contenant le formatage HTML) dans la base de données, puis le récupérer une autre fois et l'afficher. avec le même format que celui qui a été copié à partir du site web ..__, j'ai réussi en créant ces deux extensions:

extension String
{
    func getAttributedStringFromHTMLString() -> NSAttributedString
    {
        do {
            let attributedString = try NSAttributedString(data: self.dataUsingEncoding(NSUnicodeStringEncoding, allowLossyConversion: true)!, options: [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType], documentAttributes: nil)
            return attributedString
        } catch {
            print(error)
            return NSAttributedString()
        }
    }
}

extension NSAttributedString
{
    func getHTMLString() -> String
    {
        var htmlText = "";
        let documentAttributes = [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType]
        do {
            let htmlData = try self.dataFromRange(NSMakeRange(0, self.length), documentAttributes:documentAttributes)
            if let htmlString = String(data:htmlData, encoding:NSUTF8StringEncoding) {
                htmlText = htmlString
            }
            return htmlText
        }
        catch {
            print("error creating HTML from Attributed String")
            return ""
        }
    }
}
0
Claudia Fitero

Vos versions sont assez proches pour commencer. Comme Leonardo Savio Dabus a déclaré que vous devriez probablement essayer NSUTF * StringEncoding. Ce qui suit produit votre sortie attendue pour moi. Comme il l'a dit, vous voudrez peut-être l'ajouter à une extension de chaîne, si vous le faites souvent. 

    let theString = "F&uuml;r mehr Informationen klicken sie <a href=\"http://www.samplelink.com/subpage.php?id=8\">here</a>."
    let theAttributedString = NSAttributedString(data: str.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true)!,
                                                 options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil, error: nil)
    theTextView.attributedText = atString
0
Jeremy Pope

Une autre façon que j'avais l'habitude de faire cela: 

var someHtmlString = "F&uuml;r mehr Informationen klicken sie <a href=\"http://www.samplelink.com/subpage.php?id=8\">here</a>."
let regex = try! NSRegularExpression(pattern: "<.*?>", options: [.CaseInsensitive])
let range = NSRange(location: 0, length: someHtmlString.characters.count)
let htmlLessString: String = regex.stringByReplacingMatchesInString(someHtmlString, options: NSMatchingOptions(), range:range, withTemplate: "")

Résultat final -> htmlLessString is 

"F&uuml;r mehr Informationen klicken sie here."
0
Nebojsa Nadj

Après avoir créé votre chaîne attribuée, vous définissez la propriété attributedText de la UITextView comme étant la NSAttributedString elle-même, et non la propriété string de cette chaîne attribuée.

0
Rob