TestsTested | ✗ |
LangLanguage | Obj-CObjective C |
License | MIT |
ReleasedLast Release | May 2014 |
Maintained by James Tang.
Ported back NSAttributeString in iOS 5 for you to use Attributed UILabel in Interface Builder. (experimental)
NSAttributedString UIKit Additions is newly introduced in iOS 6. There it gives the power to developers to specifiy NSAttributedString into common UI elements such as UILabel, UIButton, etc, without digging into complex CoreText APIs.
While there are already out there a few libraries such as TTTAttributedLabel, RTLabel, OHAttributedLabel, etc. All of them are quite powerful yet support various kinds of markups, but I couldn't find one bridging back the missing piece - to support direct specifying NSAttributedString to UILabel in Interface Builder for iOS 5. And here the JTAttributedLabel is the project trying to port back the missing part.
In Interface Builder, if you specify an NSAttributedString in UILabel, the SDK is clever enough to make your view configuration compatible with iOS 5, but returns to a plain text layout.
The first problem for me is how we can extract the NSAttributedString out from UILabel we put into Interface builder. The attributedText
property is missing from the UILabel class in iOS 5. I remembered UI elements get -[UIView initWithCoder:]
called once they've been initialized by the OS, and I believe there's somewhere I can find the hidden attributedText
.
NSCoder
is not like NSDictionary
where we can simply use NSLog to print out the encapsulated properties. Thanks to @nicklockwood hints on using NSProxy
, it is simple enough for me to create a straight forward NSProxy subclass to wrap around the NSCoder
object and see how iOS 6 deal with it. And there I discover the "UIAttributedText" key.
Having the attributedText in hand I immediately tried to assign it into those rich text UILabel libraries. I thought it was that simple but then it causes mysterous crashes in the CoreText APIs. After some investigaion I realized the underlying implementation of the NSAttributedString is slightly different. iOS 6 seems to include a new class NSParagraphStyle
that holds the text attributes.By borrowing the techique from @hlfcoding in his RRAutoLayout introduction, I am able to implement the NSParagraphStyle
conditionally in runtime like so:
if( ! NSClassFromString(@"NSParagraphStyle") ){
objc_registerClassPair(objc_allocateClassPair([JTParagraphStyle class], "NSParagraphStyle", 0));
}
So its in different data structure than the CoreText compliment. I realized I have to translate the iOS 6 NSAttributeString into an iOS 5 compatible version, there I found some features which couldn't be mapped stated down at "Known Issues".
So after all that, I create a subclass of UILabel
with a CATextLayer
to layout the NSAttributeString. And now we've a light weight but imperfect implementation.
Drop all header and implementation files in JTAttributedLabel/JTAttributedLabel to your project.
In your Interface Builder, drag in a UILabel and specify its subclass to JTAttributedLabel
or JTAutoLabel
.
The difference between JTAttributedLabel
and JTAutoLabel
is the latter one will automatically use iOS 6 default UILabel
class for best displaying result.
There are some also some really popular libraries that brought back iOS 6 goodies for iOS 5.
Enjoy and please feel free to fork and comments!
JTAttributedLabel is under MIT LICENSE Made by James Tang @mystcolor