顶部alignmentUILabel中不同大小的文本

如何在UILabel中alignment不同大小的文本? 一个例子是在价格横幅上调整较小尺寸的美元数量和较大尺寸的美元数量。

示例图像

iOS6中的UILabel支持NSAttributedString ,它允许我在同一个UILabel中有不同大小的文本。 但是,它似乎没有用于顶部alignment文本的属性。 有什么select来实现这个? 在我看来,提供一个自定义的绘图逻辑来完成基于自定义属性string键的顶部alignment可能是最好的,但我不知道如何去做。

我能够使用单个标签实现您想要的结果。

使用一个小math可以抵消较小文本的基线,以达到您想要的结果。

 - (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; } } 

这产生以下结果:

试图简单地通过alignment框架的起源来做到这一点的问题是,“正常的”字符通常最终会在它们周围留下一些额外的填充,因为标签必须容纳所有字体的字符,包括高的上升和下降的字符。 你会注意到在你发布的图片中,如果较小的“99”是一个单独的标签,被设置为与较大的文本相同的起源,由于美元符号的最高点,它将会太高。

幸运的是, UIFont为我们提供了所需的所有信息,以便正确执行此操作。 我们需要测量标签正在使用的空的上行空间,并调整相对位置来解释它,如下所示:

 //Make sure the labels hug their contents [self.bigTextLabel sizeToFit]; [self.smallTextLabel sizeToFit]; //Figure out the "blank" space above normal character height for the big text UIFont *bigFont = self.bigTextLabel.font; CGFloat bigAscenderSpace = (bigFont.ascender - bigFont.capHeight); //Move the small text down by that ammount CGFloat smallTextOrigin = CGRectGetMinY(self.bigTextLabel.frame) + bigAscenderSpace; //Figure out the "blank" space above normal character height for the little text UIFont *smallFont = self.smallTextLabel.font; CGFloat smallAscenderSpace = smallFont.ascender - smallFont.capHeight; //Move the small text back up by that ammount smallTextOrigin -= smallAscenderSpace; //Actually assign the frames CGRect smallTextFrame = self.smallTextLabel.frame; smallTextFrame.origin.y = smallTextOrigin; self.smallTextLabel.frame = smallTextFrame; 

(这段代码假设你有两个标签属性分别叫做bigTextLabelsmallTextLabel


编辑:

这样做没有两个标签是非常相似的。 你可以使用-drawInRect:options:context: method(确保在你的选项中使用NSStringDrawingUsesLineFragmentOrigin )来创build一个自定义的UIView子类并在其中绘制NSAttributedStrings 。 计算顶部alignment方式的math应该是相同的,唯一的区别是您通过NSFontAttributeName属性(而不是标签)从属性string获取字体。 2012年的WWDCvideo归属string绘图是一个很好的参考。

这太糟糕了。 我没有足够的信誉来评论我经过一些修改后使用得很好的答案。 我只想指出,使用smallfont而不是font ,这可能是一个错字。

以下是修改后的代码

 - (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; } } 

一种可能的方法是将标签放在正在input的文本的确切大小上。

 CGRect labelFrame; //Set the origin of the label to whatever you want labelFrame.size = [label.text sizeWithFont:label.font]; //If using NSString labelFrame.size = [label.text size]; //If using NSAttributedString label.frame = labelFrame; 

看到这个类似的SO贴子更多的细节 。