Ios NSString drawInRect:withAttributes:使用NSKernAttributeName时未正确居中

Ios NSString drawInRect:withAttributes:使用NSKernAttributeName时未正确居中,ios,nsstring,core-graphics,text-alignment,kerning,Ios,Nsstring,Core Graphics,Text Alignment,Kerning,当我使用drawInRect:withAttributes:并传入带有NSTextAlignmentCenter的段落样式和nskernatributeName的非零值时,字符串无法正确居中。是我做错了什么,还是这是我期望的行为?有解决办法吗 截图: 您可以清楚地看到顶部文本没有正确居中 我的演示代码: - (void)drawRect:(CGRect)rect { // Drawing code UIFont *font = [UIFont systemFontOfSize:

当我使用
drawInRect:withAttributes:
并传入带有
NSTextAlignmentCenter
的段落样式和
nskernatributeName
的非零值时,字符串无法正确居中。是我做错了什么,还是这是我期望的行为?有解决办法吗

截图:

您可以清楚地看到顶部文本没有正确居中

我的演示代码:

- (void)drawRect:(CGRect)rect
{
    // Drawing code
    UIFont *font = [UIFont systemFontOfSize:15.0];
    [self drawString:@"88" inRect:rect font:font textColor:[UIColor blackColor]];

    CGContextRef context = UIGraphicsGetCurrentContext();
    CGContextSaveGState(context);
    CGContextAddRect(context, rect);
    CGContextStrokePath(context);
    CGContextRestoreGState(context);
}

- (void)drawString:(NSString *)text
            inRect:(CGRect)contextRect
              font:(UIFont *)font
         textColor:(UIColor *)textColor
{
    CGFloat fontHeight = font.lineHeight;
    CGFloat yOffset = floorf((contextRect.size.height - fontHeight) / 2.0) + contextRect.origin.y;

    CGRect textRect = CGRectMake(contextRect.origin.x, yOffset, contextRect.size.width, fontHeight);

    NSMutableParagraphStyle *paragraphStyle = [[NSParagraphStyle defaultParagraphStyle] mutableCopy];
    paragraphStyle.lineBreakMode = NSLineBreakByClipping;
    paragraphStyle.alignment = NSTextAlignmentCenter;

    [text drawInRect:textRect withAttributes:@{NSKernAttributeName: @(self.kerning),
                                            NSForegroundColorAttributeName: textColor,
                                            NSFontAttributeName: font,
                                            NSParagraphStyleAttributeName: paragraphStyle}];
}
谢谢

更新,多亏了,我在属性中添加了
NSBackgroundColorAttributeName:[UIColor greenColor]
,并得到以下结果:


必须仅对每个紧排对的第一个字符应用紧排。 如果要显示所有
n
字符之间具有字距的字符串,则 必须为第一个
n-1
字符设置属性

而不是:

[text drawInRect:textRect withAttributes:@{NSKernAttributeName: @(self.kerning),
                                        NSForegroundColorAttributeName: textColor,
                                        NSFontAttributeName: font,
                                        NSParagraphStyleAttributeName: paragraphStyle}];
您必须创建一个属性化字符串,以便设置紧排属性 对于特定范围而不是整个字符串:

NSMutableAttributedString *as = [[NSMutableAttributedString alloc]
                                 initWithString:text
                                 attributes:@{
                                              NSForegroundColorAttributeName: textColor,
                                              NSFontAttributeName: font,
                                              NSParagraphStyleAttributeName: paragraphStyle}];
[as addAttribute:NSKernAttributeName
           value:@(self.kerning)
           range:NSMakeRange(0, [text length] - 1)];

[as drawInRect:textRect];
下面是字符串“1234”和紧排-4.0的结果:


我想知道,如果你把它添加到绘图
NSBackgroundColorAttributeName
,它就“居中”了。观察得好,这是真的!但这甚至是一个不同的错误:因为背景颜色不适用于整个文本。你能提供一个截图吗(有两个案例)?这只是猜测。但我想那会有帮助的。我经常为一些UI元素提供亮丽的背景色来检查它们的框架,所以我建议在这里也这样做。非常感谢!太完美了!我也在寻找“跟踪”而不是“紧排”属性,但我没有找到。@JohannesFahrenkrug:“跟踪”是什么意思?紧排是针对特定的字母对,跟踪更一般: