Using UIWebView for displaying Rich Text

If you need to display rich text in your iOS application, the easiest way is to use a UIWebView for this. If you have only one or two links in a text, activating link detection in a UITextView might be the fastest way. However, you not always want to display the full link to the user or you might want to structure the text with headings or colors etc. In all these cases, the UIWebView gives you the full power of HTML.

Since integrating the UIWebView is not straight forward for all features, you can find here a summary on how to accomplish this.

What do we want to achieve?

First, let’s define what we want to do: The view should behave like a normal text view, but display rich text instead of normal text only. This also means that in some cases, we want to have a transparent background and if the user clicks a link, the page should be opened in the external browser.

Adding the UIWebView

The UIWebView can be added to your view as you do with any other view, either programmatically or using the Interface Builder.

Setting the Text

To set the text, you call the method loadHTMLString:baseURL: on your instance of the UIWebView. You can set the baseURL to nil if you want. For the content string you have to keep in mind that the view is made to display HTML pages. Therefore, you have to provide valid HTML content for the HTML string.
Setting a very basic HTML string could look like the following:

NSString* plainContent = @"My <strong>HTML</strong> markup";
NSString* htmlContentString = [NSString stringWithFormat:
  @"<html>"
   "<body>"
   "<p>%@</p>"
   "</body></html>", plainContent];

[webView loadHTMLString:htmlContentString baseURL:nil];

Setting Text Properties

If you want to change the font, the font size or other markup related properties, you have provide this properties in the HTML string, e.g. by setting the body style. Of course, you can use the full power of CSS, but we want to keep this article simple. So, to set font and font size for the whole document you can use the following code (note the additional style element for the body):

NSString* plainContent = @"My <strong>HTML</strong> markup";
NSString* htmlContentString = [NSString stringWithFormat:
    @"<html>"
     "<style type="text/css">"
     "body { font-family:Marker Felt; font-size:24;}"
     "</style>"
     "<body>"
     "<p>%@</p>"
     "</body></html>", plainContent];

[webView loadHTMLString:htmlContentString baseURL:nil];

Transparent Background

If you want to have a transparent background for your UIWebView, you have to set this property on two places. First, you have to set the background color of the view itself to be transparent. But since the webpage you display also has a background color, this is not enough. Therefore, you also have to set the background color of the HTML content to be transparent by setting the background property of the body style to „transparent“:

[webView setBackgroundColor:[UIColor clearColor]];

NSString* plainContent = @"My <strong>HTML</strong> markup";
NSString* htmlContentString = [NSString stringWithFormat:
     @"<html>"
      "<style type="text/css">"
      "body { background-color:transparent; font-family:Marker Felt; font-size:24;}"
      "</style>"
      "<body>"
      "<p>%@</p>"
      "</body></html>", plainContent];

[webView loadHTMLString:htmlContentString baseURL:nil];

Open links in External Browser

By default, the UIWebView handles links by itself and loads and displays the linked content. Since we do not want this behavior we need to catch clicks on links and forward them to Safari (or any other app that handles the clicked URL).

UIWebView provides a delegate property for this, where you can set a delegate implementing the UIWebViewDelegate protocol. The important method for us is webView:shouldStartLoadWithRequest:navigationType:

So in viewDidLoad you could set the delegate to an instance of an object implementing the following method:

- (BOOL)webView:(UIWebView *)webView shouldStartLoadWithRequest:(NSURLRequest *)request navigationType:(UIWebViewNavigationType)navigationType
{
    if ( navigationType == UIWebViewNavigationTypeLinkClicked )
    {
        [[UIApplication sharedApplication] openURL:[request URL]];
        return NO;
    }

    return YES;
}

If a link is clicked, we just forward the linked URL and let the OS handle it using the default application.

Important side note: If you set a delegate to the UIWebView, do not forget to set it to nil before releasing it, e.g. in your dealloc method, like it is mentioned in the UIWebView documentation.

Conclusion

Using the UIWebView for displaying rich text is not difficult when keeping in mind, that you are actually using a full web browser. Following these simple steps allows you to integrate the UIWebView very easily:

  1. Add the UIWebView to your view hierarchy as you would do with any other view
  2. Set the text by wrapping it into a simple HTML markup
  3. Set the text and content properties by changing the body style of your HTML markup
  4. Implement the UIWebViewDelegate protocol and set the delegate of your UIWebView to forward clicked links to the default handler