Embed links in a UILabel

Screenshot from the KILabelDemo application.

You often see apps with links, hashtags and usernames embedded in labels. I’m thinking of the many Twitter and Facebook clients out there in particular. I wanted to achieve the same effect in a client app I’m writing but there didn’t seem to be a nice way to do it with the native UIKit controls. Yes, I know it’s possible to get close to what I need with UITextView, but this isn’t easy to extend with new link types and introduces problems with interaction when its in a table cell. I tried a few open source UILabel replacements that I found and they all seemed a bit buggy or at least wouldn’t work how I expected them to.

I’ve ended up writing my own UILabel replacement, which you can find here on Github. KILabel is an extension of UILabel that adds the ability to automatically hi-light URLs, twitter style @usernames and #hashtags. It also provides a simple way to respond to users tapping on any of these using blocks. To use it just include the source code in your project and set the custom class of any labels in your nibs to KILabel.

KILabel uses ARC and TextKit so it’s iOS 7 only. It overrides UILabel’s text rendering to use a NSLayoutManager, NSTextContainer and NSTextStorage for rendering text. TextKit gives simple access to all sorts of text rendering operations which allow things like this to be implemented. There’s a useful TextKit primer here for those that are interested and my source code is quite heavily commented so it shouldn’t be too difficult to understand what’s going on.

I plan on extending KILabel as I need to, but if anyone else finds it useful and has any feature requests, please pop them in the comments.

Update: It’s been quite a while since I first release KILabel. Over that time I’ve had a few requests for help and new features. There’s now an update that you can read about here that addresses those issues and adds support for Swift and CocoaPods. – 1st May 2015

Leave a Reply

Your email address will not be published. Required fields are marked *