Appcelerator Blog

The Leading Resource for All Things Mobile

How to change the color of links in Attributed Strings

0 Flares 0 Flares ×

Since Titanium 3.2 you can use Attributed Strings on iOS and in 4.0 we added support for Android. They are a great alternative for using heavy WebViews to display formatted text.

Attributed Strings can also include links. By listening to the link event of a label you can handle the link, for example opening it in a SafariDialog or via Ti.Platform.openURL().

Overriding the the default style

Both platforms apply a default color to links and until Titanium 5.2.1 you couldn’t override that. Let me show you how in the following sample:

aslinks

Before

Let’s start out with a Window in vertical layout that uses a helper method to create two identical labels. The helper uses an attributed string with a single link in it. It also adds a listener so we can actually open the link when the user taps on it.

var win = Ti.UI.createWindow({
    layout: 'vertical'
});

win.add(createLabel());

var lbl = createLabel();
// colorLinks(lbl.attributedString);
win.add(lbl);

win.open();

function createLabel() {

    var label = Ti.UI.createLabel({
        top: 50,
        attributedString: Ti.UI.createAttributedString({
            text: 'Check out the Appcelerator Developer Portal',
            attributes: [{
                type: Ti.UI.ATTRIBUTE_LINK,
                value: 'https://developer.appcelerator.com',
                range: [14, 29]
            }]
        })
    });

    label.addEventListener('link', function(e) {
        Ti.Platform.openURL(e.url);
    });

    return label;
}

After

Now we introduce another helper that we can pass any attributed string to color the links to match our theme. We simply loop through the attributes and when we run into a link we add two more attributes to that same range. These use ATTRIBUTE_FOREGROUND_COLOR and ATTRIBUTE_UNDERLINE_COLOR to override the default color for both the main text and the underline.

function colorLinks(as) {
    var color = '#CD1625';

    as.attributes.forEach(function(attribute) {

        if (attribute.type === Ti.UI.ATTRIBUTE_LINK) {

            as.addAttribute({
                type: Ti.UI.ATTRIBUTE_FOREGROUND_COLOR,
                value: color,
                range: attribute.range
            });

            as.addAttribute({
                type: Ti.UI.ATTRIBUTE_UNDERLINE_COLOR,
                value: color,
                range: attribute.range
            });
        }
    });

    return as;
}

And that’s it! Simply wrap your attributed strings with this helper and all your links will display in the desired color. Note that in the above example the return as; isn’t required, but by adding that you can use the helper to directly wrap any call to Ti.UI.createAttributedString() as well.

Code Strong! 🚀

0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- 0 Flares ×

3 Comments

  1. Thanks for this. I’ve been working with attributedStrings recently, within a TextArea (UITextView) and had a need for the PARAGRAPH_STYLE and ATTACHMENT types for line spacing and an inserted (NSTextAttachment) image.

    I’ve figured out / hacked a way to support them by (temporarily) modifying TiAttributedStringProxy.m

    Now, I’m sure there’s got to be a simple ‘drop-in’ way I could add support with a simple module to extend this functionality rather than hack the SDK source, so where would I find a simple example of how to do that?

    Thanks!

    • You could build a Titanium iOS module that swizzles our classes to inject the new features. However, we’d also love to bring this into core. Could you create JIRA tickets for these new features and include the code for the modifications? Or do a PR that we can review and merge.

      • I’ll certainly add a ticket for adding support for it.

        I’m not so sure that my solution is good/correct enough for a PR though 😉

        But it’s certainly an addition worth doing. The paragraph styling it fairly straight forward, though I haven’t quite worked out how to properly adjust the caret height properly. But the spacing I’ve set it OK for my needs.

        The image attachment kind of works, but I have no idea how to make it react to touches for selecting/dragging.

        Here’s a copy of the TiUIAttributedStringProxy.m I’ve been fiddling with. Should be easy to see where I’ve added stuff in the addAttribute() method.

        https://gist.github.com/kosso/954c127fe0829a6d2ee9bc8ec6937701

Comments are closed.

Sign up for updates!

Become a mobile leader. Take the first step to scale mobile innovation throughout your enterprise.
Get in touch
computer and tablet showing Appcelerator software
Start free, grow from there.
0 Flares Twitter 0 Facebook 0 Google+ 0 LinkedIn 0 Email -- 0 Flares ×