How to top-align text of different sizes within a UILabel? An example is top-aligning smaller-sized cent amount with larger-sized dollar amount in price banners.
UILabel in iOS6 supports NSAttributedString
which allows me to have text of different sizes in the same UILabel. However it doesn't seem to have an attribute for top-aligning text. What are the options to implement this? It seems to me that providing a custom drawing logic to do top-alignment based on a custom attributed string key might be best but I have no idea how to go about it.
The problem with trying to do this simply by aligning the origins of frames is that "normal" characters usually end up with some extra padding around them because the label must accommodate all of the font's characters, including ones will tall ascenders and long descenders. You'll notice in the image you posted that if the smaller "99" were a separate label that was set to the same origin as the bigger text, it would be too high because of the dollar sign's top-most point.
Fortunately,
UIFont
gives us all the information we need to do this properly. We need to measure the empty ascender space the labels are using and adjust the relative positioning to account for it, like so:(This code assumes you have two label properties named
bigTextLabel
andsmallTextLabel
, respectively)Edit:
Doing this without two labels is fairly similar. You can make a custom UIView subclass and draw
NSAttributedStrings
in it with the-drawInRect:options:context:
method (make sure to useNSStringDrawingUsesLineFragmentOrigin
in your options). The math for working out the top alignment should be the same, the only difference being you get the font from the attributed string via theNSFontAttributeName
attribute, not the label. The 2012 WWDC video on attributed string drawing is a good reference for this.I was able to achieve your desired result using a single label.
Using a little math you can offset the baseline of the smaller text to achieve your desired result.
Objective-C
Swift
This yields the following: