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:
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:
Written by Scott Williams who lives and works in sunny Phoenix, AZ. Twitter is also a place.