Hashtags and Mentions in Swift

Update 11/20/2017 : The following feature is being used in Spotlight! Check it out here. https://spotlight.social/

Also, the github no longer points to latest version which fixes all the problems I had when writing this guide. I don’t plan on releasing the latest version but the current version on github will get you 95% of the functionality you want.

— — — — — — — — — — — — — — — — — — — — — — — — — — — — — — —

One of the features I recently had to implement for a yet unnamed app in development at my startup was hashtags and mentions. Here is how it looks in the product without any personalized info.

A General Overview

In order to implement the necessary functionality, I created a custom class called AttrTextView which inherits from UITextView.

The logic within AttrTextView does two main things:

  1. Sets text attributes on an incoming string.
  2. Handles the tap gesture and triggers actions upon selection of # or @

Setup

wordType is an enum we will use to refer to a word’s type, textString refers to the string you pass into AttrTextView, attrString refers to the string after attributes are applied onto it, and callBack is a function which handles what data will be displayed.

If a user clicks on a hashtag, they will be presented with search results for the hashtag, and if a user clicks on a mention, they will go to the mentioned user’s profile page if it exists.

Setting & Configuring Text

In a public setText function, you pass the string and the text attributes you want to set on it. setText will handle setting attributes and adding a tap gesture to the hashtag or mention.

Next up is setAttrWithName, a custom function that is used in setText.

Handling the Tap

After setting text attributes and adding a tap gesture recognizer, the tap is handled via a tapRecognized function. In other implementations of tap handling found on StackOverflow’s comments or on the excellent

, text is checked with a .word granularity. Sadly, this means that special characters such as # and @ are omitted!

In layman’s terms, that means that while clicking on the word itself will register properly, clicking on the “#” character or “@” character in front of the word will not register. To get around around this, I use a .character granularity so I can identify if a special character is clicked. However, my function still makes sure that the callback function can receive the full word even when a special character is clicked! How I do this is shown below with a thorough explanation in the comments.

don’t worry there will be a swift file to download at the bottom!

A Quick Demo and the Callback

Make sure to turn off the textView’s editable, scrollable, and selectable properties.

Also, insert a space at the end of the string you want to pass into setText.

And a very simple callBack function using that enum we created earlier, wordType.

“call me back baby”

Final Thoughts

Hope this post was useful and of course, you are free to use AttrTextView.

Note: Aug 1 2017 → Some screenshots might be out of date. Check repo and readme for more information.

Shoutout again to the folks at yeti for a great guide and starting point.