In tools like Photoshop and InDesign, tracking is the term that describes the relative amount of spacing between characters in a string of text.

A wonderful bit about tracking: pick a value, and your text will have that same visual style, regardless of the font size. It scales:

what tracking looks like

See how the spacing in between characters scales with the type size?

Unfortunately, tracking doesn’t exist in iOS. What we do have available is character spacing:

what character spacing looks like

See how the smaller type sizes are more spread out than their larger counterparts?

See how character spacing doesn’t look the same when you change type size? Sketch is a great help with this - when you change a label’s text size, the character spacing scales automatically - but this isn’t helpful to your iOS dev: if there are 8 different type sizes in your app, then they’ve got 8 character spacing values to worry about, rather than just a single tracking value.

So: we need a way to represent tracking in code, and when we came up against this problem, I couldn’t find a single implementation of this on the web - which meant we had to make one.

I created lots of PSDs and Sketch files, comping up different tracking values and character spacing values, and doing pixel comparisons to figure out what lined up. Once I found a match between tracking, character spacing, and font size, I put it in a spreadsheet and worked out some theories as to how the two were related - and after a bit of algebra, I found that it was actually a very simple relationship:

characterSpacing = fontSize * tracking / 1000

At first, I thought, “1000? Really? That’s the magic number?” - but then this hypothesis totally worked on other yet-untested scenarios, so that’s where we landed.

Here’s how you can put it to use:

If you want an easy way to convert between character spacing and tracking, I have a handy Soulver document here.

If you’re a dev, and you want a category method that’ll return a properly-tracked attributed string, you can find one over on GitHub here.

+ (instancetype) dvs_attributedStringWithString:(NSString *)string
   tracking:(CGFloat)tracking
   font:(UIFont *)font
{
   CGFloat fontSize = font.pointSize;
   CGFloat characterSpacing = tracking * fontSize / 1000;
   NSDictionary *attributes = @{NSFontAttributeName: font,
   NSKernAttributeName: [NSNumber numberWithFloat:characterSpacing]};

   return [[NSAttributedString alloc] initWithString:string
   attributes:attributes];
}

Here’s how you’d use it in practice:

self.label.attributedText = [NSAttributedString dvs_attributedStringWithString:@"DEVSIGN"
      tracking:200
      font:[UIFont systemFontOfSize:17.f]];