When I was creating my new app, iRachunek using iOS6 developer betas I wanted to make use of the new NSAttributedString class and create some cells using UILabel’s new attributedText property. As soon as I ran my project in Simulator I found out that when highlighting cells the attributed text doesn’t turn white. I asked on devforums.apple.com but nobody answered my question. So I decided to make it myself and ended in subclassing both UILabel and UITableViewCell. Here’s what I figured:

1. There can’t exist anything like highlightedAttributedTextColor

Since NSAttributedString is a string with many attributes, I can’t assign a ‘highlighted’ text color to it. What I have to do, is create a new NSAS property called highlightedAttributedText in my UILabel’s subclass. The next thing was making sure that I sore somewhere the original attributedText contents, so I’ve created a private NSAS iVar called attributedTextCopy. And then the method subclassing mayhem began.

The first method in the queue was -setAttributedText:, because I had to store the copy instance. The next, most important method, was, of course, -setHighlighted:. If you look into the code, you will se a strange BOOL: shouldChangeCopyInstance. What’s the point? Well, the point is, that when we change the attributedText property the attributedTextCopy mustn’t take the new value and I suppose you know why. The last method is the common -initWithFrame: to make sure that our BOOL is true on init.

So, we’ve successfully created an UILabel subclass. The next thing I’ve figured out was…

2. UITableViewCell labels must be instances of our new subclass

So, nothing difficult. Just to make sure you understand: I am using -setValue:ForKey: because both textLabel and detailTextLabel are readonly properties. I also can’t write simple _textLabel = ..., because this iVar is private*. After initialization, we set the highlightedColors to white for both labels.

* – this is not part of any private api, it’s a visibility aspect.

And we’re… done.

Now all you have to do is to import KSHighlightableAttributedCell.h and create the cells:

static NSString *cellID = @"Cell";
KSHighlightableAttributedCell *cell = [tableView dequeueReusableCellWithIdentifier:cellID];
if(cell == nil) cell = [[KSHighlightableAttributedCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cellID];
 
cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator;
 
NSMutableAttributedString *textLabelStr = [[NSMutableAttributedString alloc] initWithString:@"Your email (required)"];
[textLabelStr setAttributes:@{NSForegroundColorAttributeName : [UIColor lightGrayColor], NSFontAttributeName : [UIFont systemFontOfSize:17]} range:NSMakeRange(11, 10)];
cell.textLabel.attributedText = textLabelStr;
 
NSMutableAttributedString *textLabelStrH = [[NSMutableAttributedString alloc] initWithString:@"Your email (required)" attributes:@{NSForegroundColorAttributeName : [UIColor whiteColor], NSFontAttributeName : [UIFont boldSystemFontOfSize:17]}];
[textLabelStrH setAttributes:@{NSForegroundColorAttributeName : [UIColor whiteColor], NSFontAttributeName : [UIFont systemFontOfSize:17]} range:NSMakeRange(11, 10)];
cell.textLabel.highlightedAttributedText = textLabelStrH;
 
cell.detailTextLabel.text = @"n/a";
Interface Builder compatibility
You may also use Storyboards and NIBs to initialize the cell.

I hope this tutorial was useful. If so, don’t forget to follow us on Twitter and/or like us on Facebook.

The full source code is available on GitHub.