This was a doozy to produce, and since I had much help from SO contributors in putting it together, it seems fair to post the results (as an answer, below). If you’re looking for examples involving attributed strings in iOS and Core Text and scrolling, here they are assembled.
A few extra points:
Wrapping:
This is done by the attributed string’s lineBreakMode, which defaults to wrapping. You won’t be able to retrieve the soft line breaks from the string (unlike in Cocoa, where NSTextView puts ‘\n’ chars in the strings). But you don’t need to. You can rely on Core Text’s Framesetter to provide you with the string’s height in a given frame — as long as you have put leading info into the attributed string.
CATextLayer:
It’s handy to work with. All you have to do is assign an attributed string and it wraps and draws. If you have a short string to display with a chosen font, it’s great. But CATextLayer doesn’t recognize leading or indentation, so for this project I drew directly to CALayer.
Fonts:
I stuck with CTFontRef for the most part, since it is required for building an attributed string in iOS and it gives accurate leading, but there are times when it’s easier to work with a UIFont. Here’s a way to convert a CTFontRef (fontr) to a UIFont:
NSString *sFontName = (NSString *)CTFontCopyName(fontr, kCTFontPostScriptNameKey);
UIFont *font = [UIFont fontWithName:sFontName size:CTFontGetSize(fontr)];
CGSize sizeString = [string sizeWithFont:font];
[sFontName release];
If you create a UIFont from scratch, be aware that it will accept spaces in the family part of the font name, or you can smash them together, but “Bold” must be separated by a hyphen:
self.fontTickerNormal = [UIFont fontWithName:@"Helvetica Neue"
size:18.0f]; // OK
self.fontTickerIndent = [UIFont fontWithName:@"HelveticaNeue"
size:16.0f]; // OK too
self.fontTickerBold = [UIFont fontWithName:@"HelveticaNeue-Bold"
size:18.0f]; // both the smash and the hyphen are required
CTFontRef is more straightforward. All the name parts can be separated by spaces. The following works fine:
self.fontrTickerBold = CTFontCreateWithName((CFStringRef)@"Helvetica Neue Bold", 18.0f, NULL);
Answer-example to follow…
Prepare the Components:
Most examples are easier to read because they assemble the strings and their attributes all in one place (i.e. clear example), but if you don’t hang onto all the components, you’ll get bad-access exceptions when the views use the strings, so it seems best to set everything up in the UIViewController’s viewDidLoad:
Append the Strings:
(using these constants:)
Adjust the height, call drawLayer, and scroll to bottom:
Draw:
Autorotation:
I think I’ve got this right: Here’s how to unload all this stuff (the retained properties are also released in dealloc):