A Blog

Customizing the Link Color in a UITextView

August 07, 2013

UITextView’s can automatically detect URLs and treat them accordingly. This is a nice feature, but when you start to customize your UI, you might run into this situation:

eww
Ewwwwww

That contrast between the background and foreground colors makes it pretty hard to read. A quick poke through the docs and on StackOverflow reveals that there isn’t any way to change the color of the link, without resorting to private API’s.

Sooo, the best course of action is to just knuckle down and use a UIWebView to display what you want.

To try to keep things relatively sane, I first added a static html file to my project with this content:

<html>
  <head>
     <title></title>
  <style>
     html, body, div {
         background: #3D3D3D;
         font-family: HelveticaNeue-Medium, Helvetica;
         font-size: 12pt;
         color: #FAFAF1;
     }
    
     a {
         color: #FAFAF1;
     }
  </style>
  </head>
  <body>
      REPLACEME
  </body>
</html>

The CSS code is inlined in the file. There’s probably a way to keep it separate and inject it, but I didn’t need anything fancier than this.

Loading it was pretty straightforward:

+ (NSString *)htmlTemplate {
  NSString *path = [[NSBundle mainBundle] pathForResource:@"html-template" ofType:@"html"];
  return [NSString stringWithContentsOfFile:path encoding:NSUTF8StringEncoding error:nil];
}

Then on my controller I called this method from viewDidLoad:

- (void)setContentText:(NSString *)contentText {
  NSString *template = [SNDThemeManager attributionTemplate];
  NSString *htmlText = [template stringByReplacingOccurrencesOfString:@"REPLACEME" withString:contentText];
  [contentView loadHTMLString:htmlText baseURL:nil];
}

contentView is the UIWebView. Almost done. If you tap on a link in the webview it’ll open that link in itself, which might not be what you want. The way around it is to set your controller to be a UIWebViewDelegate and implement this method:

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

That’ll open it in Safari. If you want other browsers, well, knock yourself out. This is pretty much a giant mess for something that should be easy, but it’s just something that would have to be done if you want total control over the UI. The end result looks well enough:

Yay!
Yay!

Scott Williams

Written by Scott Williams who lives and works in sunny Phoenix, AZ. Twitter is also a place.