Swift: HTML verilerini bir etiket veya textView'da görüntüleyin


86

Başlıklar, paragraflar, resimler ve liste etiketleri içeren bazı HTML verilerim var.

Bu veriyi bir UITextViewveya birden fazla göstermenin bir yolu var mı UILabel?


1
UITextView veya UILabel yerine UIWebView kullanın. Böylece görüntüler dahil gösterilecek
Tyson Vignesh

Evet, haklı olduğunu düşünüyorum @TysonVignesh
Talha Ahmad Khan

@TysonVignesh html'yi görüntülemek için UIWebView'ı nasıl kullanabilirim?
Mohamed Ezzat

Yanıtlar:


215

Swift 5 için:

extension String {
    var htmlToAttributedString: NSAttributedString? {
        guard let data = data(using: .utf8) else { return nil }
        do {
            return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding:String.Encoding.utf8.rawValue], documentAttributes: nil)
        } catch {
            return nil
        }
    }
    var htmlToString: String {
        return htmlToAttributedString?.string ?? ""
    }
}

Sonra, HTML metnini bir UITextView'a koymak istediğinizde şunu kullanın:

textView.attributedText = htmlText.htmlToAttributedString

6
Bu benim için harika çalıştı, ancak bunun yerine label.attributedText kullanmak zorunda kaldım.
Brent Wagoner

Harika! Doğu Avrupa Latin harfleri için kodlama verilerini unicode olarak değiştirmem gerekiyordu.
nja

Harika! ancak label.attributedText, arama sırasında label.text olmalıdır
Sazzad Hissain Khan

6
Bunun görüntüleri koruması mı gerekiyor?
daredevil1234

1
@Roger Carvalho: İçerdiği html etiketleri için font-family, -size, vb. Ayarlamanın bir yolu var mı?
Bernhard Engl

35

İşte bir Swift 3 sürümü:

private func getHtmlLabel(text: String) -> UILabel {
    let label = UILabel()
    label.numberOfLines = 0
    label.lineBreakMode = .byWordWrapping
    label.attributedString = stringFromHtml(string: text)
    return label
}

private func stringFromHtml(string: String) -> NSAttributedString? {
    do {
        let data = string.data(using: String.Encoding.utf8, allowLossyConversion: true)
        if let d = data {
            let str = try NSAttributedString(data: d,
                                             options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
                                             documentAttributes: nil)
            return str
        }
    } catch {
    }
    return nil
}

Buradaki diğer cevaplardan bazılarıyla ilgili sorunlar buldum ve bunu düzeltmem biraz zaman aldı. Satır kesme modunu ve satır sayısını, HTML birden çok satıra yayıldığında etiket uygun boyutta olacak şekilde ayarladım.


HTML ayrıştırılmış ... ama yanlış. Etiketler artık görünmez, ancak kalın metin görüntülenmez. Hangi etiketlerin desteklendiğini bilmiyorum, belki desteklenmiyor <b>.
Pablo

Kalın etiketler benim için iyi çalışıyor. Çalışmayan tam html'nizi gönderebilir misiniz? Belki de kullandığınız yazı tipi kalın görünmüyor.
garie

Html, bir CMS düzenleyicisinden alınan bir metindir ve bir JSON dizesine dönmek için kodlanmıştır. Uygulama web hizmetine erişir, bu belirli metin nesnesini içeren JSON'u alır - buradaki istemcinin gereksinimi, bir web sitesinin CMS'sine (wordpress) benzer şekilde metne html etiketleri ekleme olasılığıdır. Belki dönüşü yanlış kodluyorum? JSON'u ayrıştırdığımda, hata ayıklamadaki dize dönüşünü yazdırıyorum ve '<b> </b>' dahil olmak üzere doğru görünüyor, ancak hem emülatörde hem de testler için cihazda etiketler çalışmıyor. Swift 3 kullanıyorum
Pablo

3
Nasıl özel yazı tipi ekleyebilirim?
Bhavin Ramani

14

HTML kodunuzu normal bir dizeye dönüştürmek için bu uzantıyı ekleyin:

    extension String {

        var html2AttributedString: NSAttributedString? {
            guard
                let data = dataUsingEncoding(NSUTF8StringEncoding)
            else { return nil }
            do {
                return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:NSUTF8StringEncoding], documentAttributes: nil)
            } catch let error as NSError {
                print(error.localizedDescription)
                return  nil
            }
        }
        var html2String: String {
            return html2AttributedString?.string ?? ""
        }
}

Ve sonra String'inizi bir UITextView veya UILabel içinde gösterirsiniz.

textView.text = yourString.html2String veya

label.text = yourString.html2String

1
Evet, ancak yalnızca HTML'deki metin için çalışır. Resimler ve listeler konusunda da endişeliydim. Resimleri ve listeleri göstermenin herhangi bir yolu var mı?
Talha Ahmad Khan

@TalhaAhmadKhan, Görselleriniz varsa doğrudan bir UIWebView kullanabilirsiniz. TextView veya etiketler bildiğiniz gibi çalışmayacaktır.
Sathe_Nagaraja

8

Bundan sonra metnin niteliklerini değiştirmekte sorun yaşadım ve başkalarının nedenini sorduğunu görebiliyordum ...

Bu yüzden en iyi cevap, bunun yerine NSMutableAttributedString ile uzantı kullanmaktır:

extension String {

 var htmlToAttributedString: NSMutableAttributedString? {
    guard let data = data(using: .utf8) else { return nil }
    do {
        return try NSMutableAttributedString(data: data,
                                      options: [.documentType: NSMutableAttributedString.DocumentType.html,
                                                .characterEncoding: String.Encoding.utf8.rawValue],
                                      documentAttributes: nil)
    } catch let error as NSError {
        print(error.localizedDescription)
        return  nil
    }
 }

}

Ve sonra şu şekilde kullanabilirsiniz:

if let labelTextFormatted = text.htmlToAttributedString {
                let textAttributes = [
                    NSAttributedStringKey.foregroundColor: UIColor.white,
                    NSAttributedStringKey.font: UIFont.boldSystemFont(ofSize: 13)
                    ] as [NSAttributedStringKey: Any]
                labelTextFormatted.addAttributes(textAttributes, range: NSRange(location: 0, length: labelTextFormatted.length))
                self.contentText.attributedText = labelTextFormatted
            }

Ben de aynısını elde etmek istiyorum ama yukarıdaki kod çalışmıyor.
Pratyush Pratik

7

Swift 3.0

var attrStr = try! NSAttributedString(
        data: "<b><i>text</i></b>".data(using: String.Encoding.unicode, allowLossyConversion: true)!,
        options: [ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
        documentAttributes: nil)
label.attributedText = attrStr

6

Bunu kullanıyorum:

extension UILabel {
    func setHTML(html: String) {
        do {
            let attributedString: NSAttributedString = try NSAttributedString(data: html.data(using: .utf8)!, options: [NSDocumentTypeDocumentAttribute : NSHTMLTextDocumentType], documentAttributes: nil)
            self.attributedText = attributedString
        } catch {
            self.text = html
        }
    }
}

1
Bu iyidir ancak yalnızca UILabel için geçerli olacaktır. Html alması ve atıfta bulunulan metne dönüştürülmesi gereken genel bir uzantı olması çok daha iyi olurdu.
i.AsifNoor

4

Hızlı 3

extension String {


var html2AttributedString: NSAttributedString? {
    guard
        let data = data(using: String.Encoding.utf8)
        else { return nil }
    do {
        return try NSAttributedString(data: data, options: [NSDocumentTypeDocumentAttribute:NSHTMLTextDocumentType,NSCharacterEncodingDocumentAttribute:String.Encoding.utf8], documentAttributes: nil)
    } catch let error as NSError {
        print(error.localizedDescription)
        return  nil
    }
}
var html2String: String {
    return html2AttributedString?.string ?? ""
 }
}

1
swift 3.1 NSCharacterEncodingDocumentAttribute: String.Encoding.utf8.rawValue
Can Aksoy

4

Swift 5

extension UIColor {
    var hexString: String {
        let components = cgColor.components
        let r: CGFloat = components?[0] ?? 0.0
        let g: CGFloat = components?[1] ?? 0.0
        let b: CGFloat = components?[2] ?? 0.0

        let hexString = String(format: "#%02lX%02lX%02lX", lroundf(Float(r * 255)), lroundf(Float(g * 255)),
                               lroundf(Float(b * 255)))

        return hexString
    }
}
extension String {
    func htmlAttributed(family: String?, size: CGFloat, color: UIColor) -> NSAttributedString? {
        do {
            let htmlCSSString = "<style>" +
                "html *" +
                "{" +
                "font-size: \(size)pt !important;" +
                "color: #\(color.hexString) !important;" +
                "font-family: \(family ?? "Helvetica"), Helvetica !important;" +
            "}</style> \(self)"

            guard let data = htmlCSSString.data(using: String.Encoding.utf8) else {
                return nil
            }

            return try NSAttributedString(data: data,
                                          options: [.documentType: NSAttributedString.DocumentType.html,
                                                    .characterEncoding: String.Encoding.utf8.rawValue],
                                          documentAttributes: nil)
        } catch {
            print("error: ", error)
            return nil
        }
    }
}

Ve son olarak UILabel oluşturabilirsiniz:

func createHtmlLabel(with html: String) -> UILabel {
    let htmlMock = """
    <b>hello</b>, <i>world</i>
    """

    let descriprionLabel = UILabel()
    descriprionLabel.attributedText = htmlMock.htmlAttributed(family: "YourFontFamily", size: 15, color: .red)

    return descriprionLabel
}

Sonuç:

görüntü açıklamasını buraya girin

Eğiticiye bakın:

https://medium.com/@valv0/a-swift-extension-for-string-and-html-8cfb7477a510


3

Swift 5 için ayrıca css yükleyebilir.

extension String {
    public var convertHtmlToNSAttributedString: NSAttributedString? {
        guard let data = data(using: .utf8) else {
            return nil
        }
        do {
            return try NSAttributedString(data: data,options: [.documentType: NSAttributedString.DocumentType.html,.characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
        }
        catch {
            print(error.localizedDescription)
            return nil
        }
    }

    public func convertHtmlToAttributedStringWithCSS(font: UIFont? , csscolor: String , lineheight: Int, csstextalign: String) -> NSAttributedString? {
        guard let font = font else {
            return convertHtmlToNSAttributedString
        }
        let modifiedString = "<style>body{font-family: '\(font.fontName)'; font-size:\(font.pointSize)px; color: \(csscolor); line-height: \(lineheight)px; text-align: \(csstextalign); }</style>\(self)";
        guard let data = modifiedString.data(using: .utf8) else {
            return nil
        }
        do {
            return try NSAttributedString(data: data, options: [.documentType: NSAttributedString.DocumentType.html, .characterEncoding: String.Encoding.utf8.rawValue], documentAttributes: nil)
        }
        catch {
            print(error)
            return nil
        }
    }
}

Bundan sonra, NSAttributedString'e dönüştürmek istediğiniz dizenize gidin ve aşağıdaki örnekte olduğu gibi yerleştirin:

myUILabel.attributedText = "Swift is awesome&#33;&#33;&#33;".convertHtmlToAttributedStringWithCSS(font: UIFont(name: "Arial", size: 16), csscolor: "black", lineheight: 5, csstextalign: "center")

görüntü açıklamasını buraya girin İşte her parametrenin aldığı şey:

  • yazı tipi: Bir UILabel / UITextView'da genellikle yaptığınız gibi, özel yazı tipinizin adı ve boyutuyla UIFont kullanarak yazı tipinizi ekleyin.
  • csscolor: "# 000000" gibi HEX formatında renk ekleyin veya "siyah" gibi rengin adını kullanın.
  • lineheight: Bir UILabel / UITextView'da birden fazla satırınız olduğunda satırlar arasındaki boşluktur.
  • csstextalign: Metnin hizalanmasıdır, eklemeniz gereken değer "sola" veya "sağa" veya "ortaya" veya "yasla" dır

Referans: https://johncodeos.com/how-to-display-html-in-uitextview-uilabel-with-custom-color-font-etc-in-ios-using-swift/


2

Bunu dene:

let label : UILable! = String.stringFromHTML("html String")

func stringFromHTML( string: String?) -> String
    {
        do{
            let str = try NSAttributedString(data:string!.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: true
                )!, options:[NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType, NSCharacterEncodingDocumentAttribute: NSNumber(unsignedLong: NSUTF8StringEncoding)], documentAttributes: nil)
            return str.string
        } catch
        {
            print("html error\n",error)
        }
        return ""
    }

Umarım yardımcı olur.


Evet, ancak yalnızca HTML'deki metin için çalışır. Resimler ve listeler konusunda da endişeliydim. Resimleri ve listeleri göstermenin herhangi bir yolu var mı?
Talha Ahmad Khan

3
Kullanılarak unutulmamalıdır NSHTMLTextDocumentTypeolan son derece yavaş [1]. Bunun yerine DDHTML gibi bir kitaplık kullanmayı deneyin ve kullanın . [1] robpeck.com/2015/04/nshtmltextdocumenttype-is-slow
Christopher Kevin Howell

2

Yukarıdaki cevap için teşekkürler Swift 4.2


extension String {

    var htmlToAttributedString: NSAttributedString? {
        guard
            let data = self.data(using: .utf8)
            else { return nil }
        do {
            return try NSAttributedString(data: data, options: [
                NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html,
                NSAttributedString.DocumentReadingOptionKey.characterEncoding: String.Encoding.utf8.rawValue
                ], documentAttributes: nil)
        } catch let error as NSError {
            print(error.localizedDescription)
            return  nil
        }
    }

    var htmlToString: String {
        return htmlToAttributedString?.string ?? ""
    }
}


1

Görüntüleri ve metin paragraflarını görüntülemek mümkün değildir UITextViewveya UILabelbunun için a kullanmanız gerekir UIWebView.

Öğeyi film şeridine ekleyin, kodunuza bağlantı verin ve URL'yi yüklemek için çağırın.

OBJ-C

NSString *fullURL = @"http://conecode.com";
NSURL *url = [NSURL URLWithString:fullURL];
NSURLRequest *requestObj = [NSURLRequest requestWithURL:url];
[_viewWeb loadRequest:requestObj];

Swift

let url = NSURL (string: "http://www.sourcefreeze.com");
let requestObj = NSURLRequest(URL: url!);
viewWeb.loadRequest(requestObj);

Adım adım öğretici. http://sourcefreeze.com/uiwebview-example-using-swift-in-ios/


Her ikisinde de mümkündür. Dizenin doğru şekilde kodlanması gerekiyor
froggomad

1

Swift 5

extension String {
    func htmlAttributedString() -> NSAttributedString? {
        guard let data = self.data(using: String.Encoding.utf16, allowLossyConversion: false) else { return nil }
        guard let html = try? NSMutableAttributedString(
            data: data,
            options: [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html],
            documentAttributes: nil) else { return nil }
        return html
    }
}

Aramak:

myLabel.attributedText = "myString".htmlAttributedString()

0

Bu üstünden biraz bakacağız ama ... biliyorum Bu kod UILabel, UITextView, UIButton html desteği katacak ve kolayca dize destek atfedilen olan herhangi bir görünüme bu desteği ekleyebilirsiniz:

public protocol CSHasAttributedTextProtocol: AnyObject {
    func attributedText() -> NSAttributedString?
    func attributed(text: NSAttributedString?) -> Self
}

extension UIButton: CSHasAttributedTextProtocol {
    public func attributedText() -> NSAttributedString? {
        attributedTitle(for: .normal)
    }

    public func attributed(text: NSAttributedString?) -> Self {
        setAttributedTitle(text, for: .normal); return self
    }
}

extension UITextView: CSHasAttributedTextProtocol {
    public func attributedText() -> NSAttributedString? { attributedText }

    public func attributed(text: NSAttributedString?) -> Self { attributedText = text; return self }
}

extension UILabel: CSHasAttributedTextProtocol {
    public func attributedText() -> NSAttributedString? { attributedText }

    public func attributed(text: NSAttributedString?) -> Self { attributedText = text; return self }
}

public extension CSHasAttributedTextProtocol
        where Self: CSHasFontProtocol, Self: CSHasTextColorProtocol {
    @discardableResult
    func html(_ text: String) -> Self { html(text: text) }

    @discardableResult
    func html(text: String) -> Self {
        let html = """
                   <html><body style="color:\(textColor!.hexValue()!); 
                                font-family:\(font()!.fontName); 
                                font-size:\(font()!.pointSize);">\(text)</body></html>
                   """
        html.data(using: .unicode, allowLossyConversion: true).notNil { data in
            attributed(text: try? NSAttributedString(data: data, options: [
                .documentType: NSAttributedString.DocumentType.html,
                .characterEncoding: NSNumber(value: String.Encoding.utf8.rawValue)
            ], documentAttributes: nil))
        }
        return self
    }
}


public protocol CSHasFontProtocol: AnyObject {
    func font() -> UIFont?
    func font(_ font: UIFont?) -> Self
}

extension UIButton: CSHasFontProtocol {
    public func font() -> UIFont? { titleLabel?.font }

    public func font(_ font: UIFont?) -> Self { titleLabel?.font = font; return self }
}

extension UITextView: CSHasFontProtocol {
    public func font() -> UIFont? { font }

    public func font(_ font: UIFont?) -> Self { self.font = font; return self }
}

extension UILabel: CSHasFontProtocol {
    public func font() -> UIFont? { font }

    public func font(_ font: UIFont?) -> Self { self.font = font; return self }
}

public protocol CSHasTextColorProtocol: AnyObject {
    func textColor() -> UIColor?
    func text(color: UIColor?) -> Self
}

extension UIButton: CSHasTextColorProtocol {
    public func textColor() -> UIColor? { titleColor(for: .normal) }

    public func text(color: UIColor?) -> Self { setTitleColor(color, for: .normal); return self }
}

extension UITextView: CSHasTextColorProtocol {
    public func textColor() -> UIColor? { textColor }

    public func text(color: UIColor?) -> Self { textColor = color; return self }
}

extension UILabel: CSHasTextColorProtocol {
    public func textColor() -> UIColor? { textColor }

    public func text(color: UIColor?) -> Self { textColor = color; return self }
}

-1

İÇİNDE HTML KODU OLAN BİR DİZİNİZ VARSA KULLANABİLİRSİNİZ:

extension String {
var utfData: Data? {
        return self.data(using: .utf8)
    }

    var htmlAttributedString: NSAttributedString? {
        guard let data = self.utfData else {
            return nil
        }
        do {
            return try NSAttributedString(data: data,
                                          options: [
                                            .documentType: NSAttributedString.DocumentType.html,
                                            .characterEncoding: String.Encoding.utf8.rawValue
                ], documentAttributes: nil)
        } catch {
            print(error.localizedDescription)
            return nil
        }
    }

    var htmlString: String {
        return htmlAttributedString?.string ?? self 
    }
}

VE KODUNUZDA KULLANIRSINIZ:

label.text = "something".htmlString
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.