I have text which contains HTML formatting that I am trying to render on a view. Currently I am using an NSAtributedString to display the text inside a UILabel.

I obtain the attributed string as follows:

NSString *htmlString = @"<html>"
    "  <head>"
    "    <style type='text/css'>"
    "      body { font: 12pt 'Helvetica'; color: #111111; }"
    "    </style>"
    "  </head>"
    "  <body>";
    htmlString = [htmlString stringByAppendingString:self.descriptionText];
    htmlString = [htmlString stringByAppendingString:@"</body></html>"];

    NSError *err = nil;
    NSAttributedString *attributedText = [[NSAttributedString alloc] initWithData: [htmlString dataUsingEncoding:NSUTF8StringEncoding]
                                                                          options: @{NSDocumentTypeDocumentAttribute: NSHTMLTextDocumentType}
                                                               documentAttributes: nil
                                                                            error: &err];

and then assign it to my label's attributedText property. The property self.descriptionText is an NSString which can contain simple HTML markup such as p tags or span tags with inline styles. The technique of wrapping the string in an HTML document was found on another StackOverflow post.

The UILabel is set to Lines = 0 and Line Breaks = Word Wrap. The behavior that I am seeing is that the label grows properly to accommodate the whole string, but the last line of the string is never rendered, no matter how long the string is.

Here is a screen capture with two labels. The top label (with a yellow background) has my HTML attributed string in it. You can see that the label has sized itself to allow 3 rows of text, but only two are rendered and the rest is truncated. The second label (with a red background) has had a plain string assigned to its Text property and it draws just fine.

The HTML string used in the example image contains the following text:

<p>With the world&#39;s longest fan-vaulted ceiling, an original Reubens painting, and an excellent collection of medieval stained glass, this chapel has intrigue from multiple angles</p>

screen capture with two labels. The top has an NSAttributedString, the bottom has a plain NSString.

An acceptable answer would explain how I can prevent the last line from being truncated or provide a simple alternative method for rendering HTML text to a view. Thanks.

有帮助吗?

解决方案

Ok, I figured it out. It is not an obvious solution, but I did do a face-palm after discovering it.

The problem is that the p tag is being given a margin and/or padding, which is pushing the text outside of the bounds of the UILabel. I don't know why it isn't being taken into consideration when the size of the string is computed, but I don't care anymore.

The solution was for me to add p {margin:0; padding:0;} to the style tag that I was prepending to the HTML string. Now all of the string is drawn properly inside the UILabel.

其他提示

Just ran into this as well. Apparently UILabel has some difficulties calculating the correct size when showing an attributedText that has the NSParagraphStyleAttributeName attribute set.

I solved my problem by removing this attribute from my NSMutableAttributedString before assigning it to my label like so:

[mutableAttributedString removeAttribute:NSParagraphStyleAttributeName range:NSMakeRange(0, mutableAttributedString.length)];

The effect is the same, but it feels a bit tidier than prepending some inline css.

I had the same issue with the new iOS 11.

My solution was, to insert a css line-height. Although it doesn't affect the displayed line height, it solved the issue and now all lines are displayed 🤔

body {font-size:14px;line-height:14px;}p {margin:0;padding:0;line-height:14px;}

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top