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.
Set the UILabel number of lines equal to 0 . Embed the UILabel inside an UIView . Set the UIView constraints (top, right, left and bottom) to occupy the maximum space the UILabel should grow to. Then set the UILabel to top, right, and left of the UIView and also set a constraint to bottom with distance >= 0 .
Select the text you want to Align And then press Control(ctrl)+I.
To change the font or the size of a UILabel in a Storyboard or . XIB file, open it in the interface builder. Select the label and then open up the Attribute Inspector (CMD + Option + 5). Select the button on the font box and then you can change your text size or font.
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
- (NSMutableAttributedString *)styleSalePriceLabel:(NSString *)salePrice withFont:(UIFont *)font
{
if ([salePrice rangeOfString:@"."].location == NSNotFound) {
return [[NSMutableAttributedString alloc] initWithString:salePrice];
} else {
NSRange range = [salePrice rangeOfString:@"."];
range.length = (salePrice.length - range.location);
NSMutableAttributedString *stylizedPriceLabel = [[NSMutableAttributedString alloc] initWithString:salePrice];
UIFont *smallFont = [UIFont fontWithName:font.fontName size:(font.pointSize / 2)];
NSNumber *offsetAmount = @(font.capHeight - smallFont.capHeight);
[stylizedPriceLabel addAttribute:NSFontAttributeName value:smallFont range:range];
[stylizedPriceLabel addAttribute:NSBaselineOffsetAttributeName value:offsetAmount range:range];
return stylizedPriceLabel;
}
}
Swift
extension Range where Bound == String.Index {
func asNSRange() -> NSRange {
let location = self.lowerBound.encodedOffset
let length = self.lowerBound.encodedOffset - self.upperBound.encodedOffset
return NSRange(location: location, length: length)
}
}
extension String {
func asStylizedPrice(using font: UIFont) -> NSMutableAttributedString {
let stylizedPrice = NSMutableAttributedString(string: self, attributes: [.font: font])
guard var changeRange = self.range(of: ".")?.asNSRange() else {
return stylizedPrice
}
changeRange.length = self.count - changeRange.location
// forgive the force unwrapping
let changeFont = UIFont(name: font.fontName, size: (font.pointSize / 2))!
let offset = font.capHeight - changeFont.capHeight
stylizedPrice.addAttribute(.font, value: changeFont, range: changeRange)
stylizedPrice.addAttribute(.baselineOffset, value: offset, range: changeRange)
return stylizedPrice
}
}
This yields the following:
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With