89

How can I display HTML text in textview?

For example,

string <h1>Krupal testing <span style="font-weight:
bold;">Customer WYWO</span></h1>

Suppose text is bold so it display in textview as bold string but I want display normal text. Is this possible in the iPhone SDK?

Michael Currie
  • 13,721
  • 9
  • 42
  • 58
milanjansari
  • 1,529
  • 2
  • 21
  • 33

11 Answers11

239

Use following block of code for ios 7+.

NSString *htmlString = @"<h1>Header</h1><h2>Subheader</h2><p>Some <em>text</em></p><img src='http://blogs.babble.com/famecrawler/files/2010/11/mickey_mouse-1097.jpg' width=70 height=100 />";
NSAttributedString *attributedString = [[NSAttributedString alloc]
          initWithData: [htmlString dataUsingEncoding:NSUnicodeStringEncoding]
               options: @{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType }
    documentAttributes: nil
                 error: nil
];
textView.attributedText = attributedString;
imgx64
  • 4,062
  • 5
  • 28
  • 44
Bhoopi
  • 6,523
  • 3
  • 22
  • 16
  • 7
    Hi, How to calculate height of text view? I do not want text view to be scrolling. I used textView.contensize. Did not worked. – Durgaprasad Jan 20 '14 at 06:15
  • 6
    How could I change the font of the string? Using addAttribute:NSFontAttributeName seems reset all the font(bold). – jeswang Aug 08 '14 at 22:05
  • if i want to set the img src from bundle how can we call it? i tried like this but it doesn't work @"
    Getting started with the application

    Homepage
    Upon opening the application, you will be taken to the homepage, from where can you navigate to the various sections of the app, by clicking on the navigation buttons.

    "
    – kalyani puvvada Oct 17 '14 at 10:54
  • This is a great answer. I want to add that what messed me up was trying to put string literals inside of the html instead of what's shown above. Wrong (what I was doing): html = @"ESPN"; Right: html = @"ESPN"; – Brian Sachetta Jan 14 '15 at 15:47
  • this is working like anything, but if i place this this piece of code in viewdidload method view loading very slow. any help? – naresh May 04 '15 at 12:50
  • 15
    To change the font, change `NSAttributedString` to `NSMutableAttributedString` and add `[attributedString addAttributes:@{NSFontAttributeName: font} range:NSMakeRange(0, attributedString.length)];` – Ajumal May 25 '15 at 06:51
  • 1
    To automagically size it `tv.frame = CGRectMake(0, 0, HUGE, 1); [tv sizeToFit]; ` – Gaston Morixe Jul 31 '15 at 15:18
  • 1
    @Durgaprasad to modify string's style you can create mutable copy and set your attributes to it: `NSMutableAttributedString *mString = [[NSMutableAttributedString alloc] initWithAttributedString:attributedString]; [mString addAttributes:@{NSForegroundColorAttributeName: [UIColor whiteColor]} range:NSMakeRange(0, mString.length)];` – Sound Blaster Oct 23 '15 at 14:31
  • Hi, anyone use this method in app and got approved on app store? When I use this conversion I got a debug message complaining "dlopen(/System/Library/PrivateFrameworks/DataDetectorsUI.framework/DataDetectorsUI", it has private framework involved? – Will Nov 28 '15 at 10:15
  • 1
    @GastonM Thanks a ton.. it perfectly solved the problem – Saurabh Gulia Dec 31 '15 at 17:57
  • images from url are not loading in it. is it the limitation or any modification required for this – iPhone 7 Mar 31 '16 at 07:02
  • if we use this method then any problem while uploading on app store ? – Mahesh Cheliya Apr 23 '16 at 11:47
  • @MaheshCheliya I did not face any problem while upload the app on app store. There should not be any problem. Good luck to you. – Bhoopi Apr 26 '16 at 17:54
  • @jeswang I am facing the same problem. Did you the get solution to it? – Vinayak Parmar Aug 05 '17 at 11:50
  • @BHUPI Adding attribute through addAttribute resets font of all the text. It doesn't respect bold tag and all of HTML. How to fix it. Any idea? – Vinayak Parmar Aug 05 '17 at 11:52
  • @Durgaprasad Guess you have found the answer after 4 years but in case you didn't. let height = label.systemLayoutSizeFitting(UILayoutFittingCompressedSize).height – Ke MA Feb 05 '18 at 21:41
58

For Swift 4, Swift 4.2: and Swift 5

let htmlString = """
    <html>
        <head>
            <style>
                body {
                    background-color : rgb(230, 230, 230);
                    font-family      : 'Arial';
                    text-decoration  : none;
                }
            </style>
        </head>
        <body>
            <h1>A title</h1>
            <p>A paragraph</p>
            <b>bold text</b>
        </body>
    </html>
    """

let htmlData = NSString(string: htmlString).data(using: String.Encoding.unicode.rawValue)

let options = [NSAttributedString.DocumentReadingOptionKey.documentType: NSAttributedString.DocumentType.html]

let attributedString = try! NSAttributedString(data: htmlData!, options: options, documentAttributes: nil)

textView.attributedText = attributedString

For Swift 3:

let htmlString = """
    <html>
        <head>
            <style>
                body {
                    background-color : rgb(230, 230, 230);
                    font-family      : 'Arial';
                    text-decoration  : none;
                }
            </style>
        </head>
        <body>
            <h1>A title</h1>
            <p>A paragraph</p>
            <b>bold text</b>
        </body>
    </html>
    """

let htmlData = NSString(string: htmlString).data(using: String.Encoding.unicode.rawValue)

let attributedString = try! NSAttributedString(data: htmlData!, options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType], documentAttributes: nil)

textView.attributedText = attributedString
pableiros
  • 14,932
  • 12
  • 99
  • 105
  • Is there any way to add external css to html attributed String @pableiros – Mansuu.... Aug 29 '17 at 13:25
  • @Mansuu.... You have to read the css file from your bundle: `let path = Bundle.main.path(forResource: "styles", ofType: "css")`, get the content `let content = try! String(contentsOfFile: path!, encoding: String.Encoding.utf8)` and add it to the html String – pableiros Aug 29 '17 at 15:14
  • Thanks @pableiros It worked, but not the way I want. My external css imports bootstrap.min.css. It does not work when I applying css to UItextView by getting it's content. – Mansuu.... Oct 12 '17 at 08:42
  • thanks a lot it works for my for the swift 3 :) keep it up – Amr Angry Oct 23 '17 at 15:39
55

Use a UIWebView on iOS 5-.

On iOS 6+ you can use UITextView.attributedString, see https://stackoverflow.com/a/20996085 for how.


There's also an undocumented -[UITextView setContentToHTMLString:] method. Do not use this if you want to submit to AppStore.

Community
  • 1
  • 1
kennytm
  • 510,854
  • 105
  • 1,084
  • 1,005
20

BHUPI's answer is correct, but if you would like to combine your custom font from UILabel or UITextView with HTML content, you need to correct your html a bit:

NSString *htmlString = @"<b>Bold</b><br><i>Italic</i><p> <del>Deleted</del><p>List<ul><li>Coffee</li><li type='square'>Tea</li></ul><br><a href='URL'>Link </a>";

htmlString = [htmlString stringByAppendingString:@"<style>body{font-family:'YOUR_FONT_HERE'; font-size:'SIZE';}</style>"];
/*Example:

 htmlString = [htmlString stringByAppendingString:[NSString stringWithFormat:@"<style>body{font-family: '%@'; font-size:%fpx;}</style>",_myLabel.font.fontName,_myLabel.font.pointSize]];
*/
 NSAttributedString *attributedString = [[NSAttributedString alloc]
                      initWithData: [htmlString dataUsingEncoding:NSUnicodeStringEncoding]
                           options: @{ NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType }
                documentAttributes: nil
                             error: nil
            ];
textView.attributedText = attributedString;

You can see the difference on the picture below: enter image description here

hypercrypt
  • 15,389
  • 6
  • 48
  • 59
David
  • 1,061
  • 11
  • 18
12

You can have a look the OHAttributedLabel classes, I used these to overcome this kind of problem with my textField. In this they have overridden the drawRect method to obtain the required style.

https://github.com/AliSoftware/OHAttributedLabel

sElanthiraiyan
  • 6,000
  • 1
  • 31
  • 38
9

My first response was made before iOS 7 introduced explicit support for displaying attributed strings in common controls. You may now set attributedText of UITextView to an NSAttributedString created from HTML content using:

-(id)initWithData:(NSData *)data options:(NSDictionary *)options documentAttributes:(NSDictionary **)dict error:(NSError **)error 

- initWithData:options:documentAttributes:error: (Apple Doc)

Original answer, preserved for history:

Unless you use a UIWebView, your solution will rely directly on CoreText. As ElanthiraiyanS points out, some open source projects have emerged to simplify rich text rendering. I would recommend NSAttributedString-Additions-For-HTML (Edit: the project has been supplanted DTCoreText), which features classes to generate and display attributed strings from HTML.

Alaeddine
  • 6,104
  • 3
  • 28
  • 45
Justin
  • 20,509
  • 6
  • 47
  • 58
4

Answer has fitted to me that from BHUPI.

The code transfer to swift as below:

Pay attention "allowLossyConversion: false"

if you set the value to true, it will show pure text.

let theString = "<h1>H1 title</h1><b>Logo</b><img src='http://www.aver.com/Images/Shared/logo-color.png'><br>~end~"

        let theAttributedString = try! NSAttributedString(data: theString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!,
            options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
            documentAttributes: nil)

        UITextView_Message.attributedText = theAttributedString
米米米
  • 970
  • 7
  • 9
  • 2
    `NSUnicodeStringEncoding` is correct, because NSString is Unicode-encoded, not UTF8. In case of CJK character, you won't get right answer. – DawnSong Apr 06 '16 at 07:44
3

For Swift3

    let theString = "<h1>H1 title</h1><b>Logo</b><img src='http://www.aver.com/Images/Shared/logo-color.png'><br>~end~"

    let theAttributedString = try! NSAttributedString(data: theString.dataUsingEncoding(NSUTF8StringEncoding, allowLossyConversion: false)!,
        options: [NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType],
        documentAttributes: nil)

    UITextView_Message.attributedText = theAttributedString
Ajay Iyer
  • 61
  • 2
1

For some cases UIWebView is a good solution. Because:

  • it displays tables, images, other files
  • it's fast (comparing with NSAttributedString: NSHTMLTextDocumentType)
  • it's out of the box

Using NSAttributedString can lead to crashes, if html is complex or contains tables (so example)

For loading text to web view you can use the following snippet (just example):

func loadHTMLText(_ text: String?, font: UIFont) {
        let fontSize = font.pointSize * UIScreen.screens[0].scale
        let html = """
        <html><body><span style=\"font-family: \(font.fontName); font-size: \(fontSize)\; color: #112233">\(text ?? "")</span></body></html>
        """
        self.loadHTMLString(html, baseURL: nil)
    }
HotJard
  • 4,598
  • 2
  • 36
  • 36
-2

You can also use one more way. Three20 library offers a method through which we can construct a styled textView. You can get the library here: http://github.com/facebook/three20/

The class TTStyledTextLabel has a method called textFromXHTML: I guess this would serve the purpose. But it would be possible in readonly mode. I don't think it will allow to write or edit HTML content.

There is also a question which can help you regarding this: HTML String content for UILabel and TextView

I hope its helpful.

Community
  • 1
  • 1
Dip Dhingani
  • 2,499
  • 2
  • 20
  • 18
-3

NSDoc save the text file in a string to an html file then simultaneously load it into a webview that is in the same place as your UITextView..

Albert Renshaw
  • 17,282
  • 18
  • 107
  • 195