Create Embedded Links with NSAttributedString

Joe Trent
Artificial Intelligence with a Vision
5 min readSep 10, 2016

The genesis of this project came when I first asked myself the question:

How does one embed a hyperlink inside an TextField or TextView?

It’s fairly easy to make hyperlinks clickable in a UITextView. To do so, go to the Attributes Inspector of the view and check off the “Links” option in the “Detection” field.

Doing this allows your app to detects HTTP links and turns them into hyperlinks.

This works fine for making your links clickable, but it means that what the user sees is the full link, instead of a more easily readable, embedded one. For example, if you wanted a hyperlink to Wikipedia’s page on apple pie in your app, you would have to display https://en.wikipedia.org/wiki/Apple_pie instead of the more readable apple pie.

Is there a way to make user-readable text clickable in a UITextView, UILabel, or UITextField?

Enter NSAttributedString.

From Apple’s Developer Library:

An NSAttributedString object manages character strings and associated sets of attributes (for example, font and kerning) that apply to individual characters or ranges of characters in the string. An association of characters and their attributes is called an attributed string. The cluster’s two public classes,NSAttributedString and NSMutableAttributedString, declare the programmatic interface for read-only attributed strings and modifiable attributed strings, respectively.

Essentially, NSAttributedString allows you to assign different types of attributes to your text. To assign attributes to a mutable string, you would use its subclass, NSMutableAttributedString.

Digging a little deeper into NSMutableAttributedString:

The NSMutableAttributedString class declares additional methods for mutating the content of an attributed string. You can add and remove characters (raw strings) and attributes separately or together as attributed strings.

NSMutableAttributedString adds two primitive methods to those of NSAttributedString. These primitive methods provide the basis for all the other methods in its class. The primitive replaceCharactersInRange:withString: method replaces a range of characters with those from a string, leaving all attribute information outside that range intact. The primitive setAttributes:range: method sets attributes and values for a given range of characters, replacing any previous attributes and values for that range.

So, unlike a NSAttributedString, both the contents of a NSMutableAttributedString as well as the attributes applied to it can be changed after the string has been constructed.

Xamarin depiction of NSMutableAttributedString

Great! So NSMutableAttributedString can be used to customize your strings, whether it be by changing the font, adjusting the color or even by making it an NSURL.

To play around with this useful feature, I decided to incorporate NSMutableAttributedStrings into an older project that I first talked about here.

This cupcake looks so delicious.

This project uses Clarifai’s API to recognize the contents of an image and displays tags associated with that image to the user.

What I set out to do was take the tags that were being generated by Clarifai’s API and turn them into links. In particular, each word that’s produced as a tag, would link to a query of that word in Google or Wikipedia. So if you took a picture of a brownie, the app would generate the embedded tag ‘brownie’, which would link then you directly to a Google search or a Wikipedia entry on that word.

To start, I first created an extension of the ViewController, had it adopt the UITextViewDelegate protocol and implemented some of the methods associated with that protocol. The UITextViewDelegate protocol defines a set of optional methods you can use to receive editing-related messages for UITextView objects.

Next, I created a function that took in a string and returned a NSMutableAttributedString. For each term that entered the function, I replaced its spaces with underscores and put that term into a URL (in this case, https://en.wikipedia.org/wiki/term), that was then added as an attribute to a new constant. For example, if I called this function on the word ‘ice cream’, the displayed text would be ice cream and the destination link would be https://en.wikipedia.org/wiki/Ice_cream.

Afterwards, I took separated all of the tags that were being displayed in the UITextView and applied the previous function to every generated term, thereby linking each tag to its respective Wikipedia page.

Following that, I added this new collection of embedded tags to the textView and performed some other customizations to flesh out how I wanted users to see and interact with the tags.

Great!

You have no idea how much my mouth is watering right now

Now, if you were to click on the ‘cake’ tag, it would bring you to the Wikipedia page below:

Sweet!

I hope this tutorial was interesting and helpful. If you couldn’t already tell, I’m craving all of the desserts right now, so I’m going to gorge on something sugary.

Be sure to check this project out my Github.

--

--