Is it possible to alter the letter-spacing/kerning of a font with Cocoa Touch?
cocoa-touch, core-graphics, iphone, objective-c, quartz-graphics
Solution
I landed here from Google trying to do the same with UITextField. I implemented something that'll work generically for UILabel below.
@interface AdjustableUILable : UILabel {
CGFloat characterSpacing;
}
@property CGFloat characterSpacing;
@end
@implementation AdjustableUILable
@synthesize characterSpacing;
- (void)drawTextInRect:(CGRect)rect
{
if (characterSpacing)
{
// Drawing code
CGContextRef context = UIGraphicsGetCurrentContext();
CGFloat size = self.font.pointSize;
CGContextSelectFont (context, [self.font.fontName UTF8String], size, kCGEncodingMacRoman);
CGContextSetCharacterSpacing (context, characterSpacing);
CGContextSetTextDrawingMode (context, kCGTextFill);
// Rotate text to not be upside down
CGAffineTransform xform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
CGContextSetTextMatrix(context, xform);
const char *cStr = [self.text UTF8String];
CGContextShowTextAtPoint (context, rect.origin.x, rect.origin.y + size, cStr, strlen(cStr));
}
else
{
// no character spacing provided so do normal drawing
[super drawTextInRect:rect];
}
}
@end
Then to use it, just set up the label in viewDidLoad or something
- (void)viewDidLoad
{
myLabel.characterSpacing = 2; // point size
}
I tried it with UITextField, but unfortunately it only adds the character spacing after the user has edited the field. -drawTextInRect is only called after the -textFieldShouldEndEditing delegate method. From other forums some suggested this was because UITextField needs to know the rendering of the font in order to display the cursor. Never found a solution for that piece...
Problem
I've been scouring the Internet for a while now for information on how one can alter the letter-spacing/kerning of a font within UIKit. My fear is, that like using your own custom fonts, you simply can't. Which would be terrible news. I know Apple is protecting us from bad design with these constraints, but they're also preventing us from implementing really great design too. What do people suggest I do? Use the font with the standard kerning, people probably wouldn't notice the difference anyway. Find someone's hacked class to get the look the user deserves after parting with their hard earned cash. Use the method that I've somehow overlooked, and do it with UIKit, pledging my eternal gratitude to the person who imparts this hidden nugget of knowledge.