Hashtags are used by all the major social media platforms, and for good reason – it’s a convenient tool for filtering relevant content. Not only are users already trained on using hashtags and mentions, they’re starting to expect these features in apps.
With hashtags so common in social media, one might think that building a hashtag detection feature in iOS would be easy, if not straightforward. Sadly, I did not find this to be the case when researching solutions online.
Why is this so hard?
Labels are not clickable by default, so a tap gesture is necessary. But this tap gesture applies to the entire label, so there needs to be a way to detect which specific word was tapped. The hashtag symbol further complicates matters. Word boundaries typically include special characters as delimiters, so in this situation, # and @ characters would get lost in the initial word split. Of course you can split on whitespace, but now you have to deal with special characters inside each word. And do you hashtag a number, like #1?
There are libraries out there that take care of these sorts of things. STTweetLabel is an Objective-C library which would require CocoaPods or a bridging header. If you want something in Swift, you could use a custom approach like performing hit tests to correspond tap coordinates to word locations inside the label.
One approach I came across was to give up and use a WebView. While it’s shameful to even consider this kind of hack, it does contain a clue to a better approach. What if there was a way to tag words with links as you would with HTML? And what if you could make custom URL schemes for hashtags and mentions, and then hook into the URL click event?
It turns out that the native UITextView API can do all this, and more! No need for kludgy hacks or complicated workarounds.
Know Thy API
There’s more than meets the eye with the UITextView API.
UITextView can detect link clicks. Just by checking a few boxes in the Storyboard, URLs turn blue and become clickable. You do have to make the TextView read-only, otherwise it wouldn’t be able to tell a link click from a tap to edit.
UITextView also lets you add something called a link attribute, which is similar to an “href” property on an anchor tag in HTML. Hashtags, or any section of text, can be turned into a clickable link. You’ll see why in a moment, but you can also customize the URL scheme to something other than “http.” So you can do something like “hash://foodie” for #foodie, and “mention://riblapp” for @riblapp.
UITextView has a built-in delegate method that gets called when the user clicks the URL. By default, it will do an openURL to Safari. The delegate method gives you a handle to the NSURL object, which parses the scheme and the URI for you. So in the example above, you can check for the “hash” scheme, and do something custom with the payload “foodie.”
The built-in UITextView APIs save us from writing a lot of custom code. Now all that’s left to do is wrap all this up in a library.
Here is a sample project that implements hashtag detection using the approach outlined above. It extends UITextView by adding a method that will add an URL to each hashtag. So the word #ICYMI will become clickable, having an URL with custom scheme of “hash:ICYMI.”
To install, just copy a swift file into your project. The readme includes usage instructions on how to setup the UITextView delegate to handle the custom URL scheme. Or just steal the code from the working example.
Good luck in your hashtag implementations in Swift.
Like this post? Please share it! Then follow us on Twitter @thorntech and join our mailing list below for future updates.