如何更改UILabel/UIFont的字母间距?

38

我已经进行了大量搜索,但找不到答案。

我有一个普通的UILabel,定义如下:

    UILabel *totalColors = [[[UILabel alloc] initWithFrame:CGRectMake(5, 7, 120, 69)] autorelease];
    totalColors.text = [NSString stringWithFormat:@"%d", total];
    totalColors.font = [UIFont fontWithName:@"Arial-BoldMT" size:60];
    totalColors.textColor = [UIColor colorWithRed:221/255.0 green:221/255.0 blue:221/255.0 alpha:1.0];
    totalColors.backgroundColor = [UIColor clearColor];
    [self addSubview:totalColors];

我希望字母之间的水平间距更紧密,同时保持字体大小。有没有方法可以做到这一点?这应该是一个相当基本的操作。

谢谢大家, Andre

更新:

所以我被迫像这样做:

- (void) drawRect:(CGRect)rect 
{
    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextSelectFont (context, "Arial-BoldMT", 60, kCGEncodingMacRoman);
    CGContextSetCharacterSpacing (context, -10);
    CGContextSetTextDrawingMode (context, kCGTextFill);

    CGContextSetRGBFillColor(context, 221/255.0, 221/255.0, 221/255.0, 221/255.0);
    CGAffineTransform xform = CGAffineTransformMake(1.0, 0.0, 0.0, -1.0, 0.0, 0.0);
    CGContextSetTextMatrix(context, xform);

    char* result = malloc(17);
    sprintf(result, "%d", totalNumber);

    CGContextShowTextAtPoint (context, 0, 54, result, strlen(result));
}

但我需要将其右对齐。

如果我知道绘制文本的宽度,我可以手动完成,但是找到这个宽度几乎是不可能的。

我已经阅读了有关 ATSU 的内容,但是我找不到任何示例。

这太糟糕了 :/


可能是https://dev59.com/DnNA5IYBdhLWcg3wL6oc的重复问题,是否可以使用Cocoa Touch更改字体的字距和字间距? - Can Berk Güder
那么除了使用自定义字体或不使用Quartz 2D之外,没有其他方法可以做到吗? - Andre
1
您可以通过调用NSString类别UIStringDrawing的-(CGSize)sizeWithFont:(UIFont *)font minFontSize:(CGFloat)minFontSize actualFontSize:(CGFloat *)actualFontSize forWidth:(CGFloat)width lineBreakMode:(UILineBreakMode)lineBreakMode方法来获取UILabel中文本所占区域的大小。然后,您可以根据您缩小文本的程度来减小该大小,如果您仍需要它的话 :) - Kostiantyn Sokolinskyi
如果有人需要解决方案,请在此处查看:https://dev59.com/K2s05IYBdhLWcg3wPPaB#35156265 - Arben Pnishi
查看 此答案 以计算字距(即字符之间的紧密空间)以适应标签的宽度。 - Borzh
5个回答

43

iOS 6以后,您可以在UILabel中使用NSAttributedString。

在属性字符串中,您可以使用NSKernAttributeName属性来设置字母间距。

NSMutableAttributedString* attrStr = [[NSMutableAttributedString alloc] initWithString: @"Test test test test "];
[attrStr addAttribute:NSKernAttributeName value:@(4.0) range:NSMakeRange(0, attrStr.length)];

UILabel* label = [[UILabel alloc] initWithFrame:CGRectMake(0, 300, 300, 100)];
label.attributedText = attrStr;

1
谢谢你节省了我的时间 :) (y) - ishhhh

11

我扩展了UILabel来改变字符间距。这应该可以直接使用,并从UILabel本身中提取字体、文本、颜色等(正确的编码!)。

你可能会注意到我两次绘制文本,首先用透明颜色。这是为了将文本自动居中在标签中。虽然这可能效率不高——但自动居中不是很好吗?

享受!

@interface RALabel : UILabel {
}
@end  

@implementation RALabel 

- (void) drawRect:(CGRect)rect 
{

    // Drawing code

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSelectFont (context, [self.font.fontName cStringUsingEncoding:NSASCIIStringEncoding], self.font.pointSize, kCGEncodingMacRoman);
    CGContextSetCharacterSpacing(context, 1);
    CGContextSetFillColorWithColor(context, [[UIColor clearColor] CGColor]);
    CGAffineTransform myTextTransform = CGAffineTransformScale(CGAffineTransformIdentity, 1.f, -1.f );
    CGContextSetTextMatrix (context, myTextTransform);

    // draw 1 but invisbly to get the string length.
    CGPoint p =CGContextGetTextPosition(context);
    float centeredY = (self.font.pointSize + (self.frame.size.height- self.font.pointSize)/2)-2;
    CGContextShowTextAtPoint(context, 0, centeredY, [self.text cStringUsingEncoding:NSASCIIStringEncoding], [self.text length]);
    CGPoint v =CGContextGetTextPosition(context);

    // calculate width and draw second one.
    float width = v.x - p.x;
    float centeredX =(self.frame.size.width- width)/2;
    CGContextSetFillColorWithColor(context, [self.textColor CGColor]);
    CGContextShowTextAtPoint(context, centeredX, centeredY, [self.text cStringUsingEncoding:NSASCIIStringEncoding], [self.text length]);

}

2
你只能使用ASCII字符来解决这个问题。 - Bastian

7

我想到了一个解决字母间距和右对齐的方法。

具体如下:

    NSString *number = [NSString stringWithFormat:@"%d", total];

    int lastPos = 85;

    NSUInteger i;
    for (i = number.length; i > 0; i--)
    {
        NSRange range = {i-1,1};
        NSString *n = [number substringWithRange:range];

        UILabel *digit = [[[UILabel alloc] initWithFrame:CGRectMake(5, 10, 35, 50)] autorelease];
        digit.text = n;
        digit.font = [UIFont fontWithName:@"Arial-BoldMT" size:60];
        digit.textColor = [UIColor colorWithRed:221/255.0 green:221/255.0 blue:221/255.0 alpha:1.0];
        digit.backgroundColor = [UIColor clearColor];
        [self addSubview:digit];

        CGSize textSize = [[digit text] sizeWithFont:[digit font]];
        CGFloat textWidth = textSize.width;

        CGRect rect = digit.frame;
        rect.origin.x = lastPos - textWidth;
        digit.frame = rect;

        lastPos = rect.origin.x + 10;
    }

字母间距是最后一行的“10”。 对齐方式来自lastPos。 希望这能帮助到任何需要的人。

3
你的方法很有道理(也是我首先想到的),但如果需要渲染多个文本区域,那么它可能效果不佳。我认为Andre提供的更新在一般情况下更好。 - Kostiantyn Sokolinskyi

3

在Swift中:

let myTitle = "my title"
let titleLabel = UILabel()
let attributes: NSDictionary = [
    NSFontAttributeName:UIFont(name: "HelveticaNeue-Light", size: 20),
    NSForegroundColorAttributeName:UIColor.whiteColor(),
    NSKernAttributeName:CGFloat(2.0)
]
let attributedTitle = NSAttributedString(string: myTitle, attributes: attributes as? [String : AnyObject])

titleLabel.attributedText = attributedTitle
titleLabel.sizeToFit()

0

在任何公开版本的iPhone OS中都没有。;-) 如果您是当前的iPhone开发人员,可以通过查看iPhone OS 3.2的“新功能”说明来了解iPhone OS的发展方向。

更新:当我发布这篇文章时,支持字距调整的iOS v3.2仍然受到NDA的限制。有关最新答案,请参见{{link1:如何在iPhone UILabel中设置字距}}。


您可以使用textRectForBounds:limitedToNumberOfLines:方法确定UILabel中绘制文本的尺寸。听起来您已经找到了自己想要的,不过!我之前只是假设您在寻找字距调整。祝编码愉快! - Zack
截至目前,当前的iOS版本是6.1。实现这一点(容易)的方法是通过使用“NSAttributedString”,但在iOS 6.0之前大多数控件都无法使用它。 - DBD

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接