为啥字符串格式在 UILabel 中不起作用?

Posted

技术标签:

【中文标题】为啥字符串格式在 UILabel 中不起作用?【英文标题】:Why string formatting not work in UILabel?为什么字符串格式在 UILabel 中不起作用? 【发布时间】:2015-01-20 04:24:14 【问题描述】:

如何将所有连字符设置在同一垂直位置? 我使用下一个代码:

subText = [NSString stringWithFormat:@"%3d%% - %@",subPercent,subfactor];
NSLog(@"%@",subText);
[label setText:subText];

但它看起来像:http://i.stack.imgur.com/amei7.png

在情节提要中创建并左对齐的标签。 应用在 ios 7+ 上运行

更新。

看起来很疯狂,但工作。

if (subPercent == 100) 
    subText = [NSString stringWithFormat:@"%d%% - %@",subPercent,subfactor];
 else if (subPercent > 9) 
    subText = [NSString stringWithFormat:@"  %d%% - %@",subPercent,subfactor];
 else 
    subText = [NSString stringWithFormat:@"    %d%% - %@",subPercent,subfactor];

必须是更好的解决方案。

【问题讨论】:

不幸的是,stringWithFormat 并没有严格遵守 IEEE printf 规范。 我一直不明白为什么第一个比较是最罕见的情况(1/100),它在运行时99%的情况下被毫无意义地评估......跨度> @holex - 通常,人们会首先排除“最奇怪”的情况。除非您进行过早优化,否则这通常不是问题。 @HotLicks,每个人都这么说,结果就是一个该死的慢应用程序。它只是说某人缺乏数学知识,并且没有任何优化......这将从其他地方开始,但我不会跳入这样的辩论。 ;) @holex - 在我 40 多年的编程经验中,由于错误而失败的项目要多于由于性能不佳而失败的项目。编写代码以便您理解它胜过使其快速。 【参考方案1】:

您的数字不对齐的原因是数字和空格的宽度不同。然而,在许多字体中,无论是固定宽度还是比例,所有数字都是相同的宽度,并且 Unicode 有一个“数字空间”字符 U+2007,它是一个数字宽度空间。不幸的是,printf 来自 Unicode 之前的时代,不知道图形空间。

但是NSNumberFormatter 完全支持 Unicode 和本地化。要将 0 到 100 之间的整数值格式化为 3 个等宽字符的 NSString,您首先要定义格式化程序:

NSNumberFormatter *formatter = [NSNumberFormatter new];
formatter.numberStyle = NSNumberFormatterDecimalStyle;
formatter.formatWidth = 3;
formatter.paddingCharacter = @"\u2007"; // figure (digit) space

然后用它来格式化你的数字:

int value = 42; // a value between 0 -> 100
NSString *formatted = [formatter stringFromNumber:@(value)];

(注意@(...)int 转换为NSNumber)。

您可以做得更好,让NSNumberFormatter01 之间的浮点数格式化为百分比,并在当前语言环境中使用适当的百分比符号。为此,请使用以下方式设置格式化程序:

NSNumberFormatter *formatter = [NSNumberFormatter new];
formatter.numberStyle = NSNumberFormatterPercentStyle;
formatter.formatWidth = 4; // 4 = 3 digits + percent symbol
formatter.maximumFractionDigits = 0; // so we get a whole number (unless you want x.y%)
formatter.paddingCharacter = @"\u2007"; // figure (digit) space

如果要格式化的值是整数,只需将其除以100.0

int value = 42; // a value between 0 -> 100
NSString *formatted = [formatter stringFromNumber:@(value / 100.0)];

这是一个“更好的解决方案”吗?你必须做出决定,还有很多其他的方法。

HTH

(为了好玩:如果您想坚持使用stringWithFormat,请考虑一个整数的以 10 为底的对数告诉您它有多少位,并且您可以打印字符串(想想填充)可变字段宽度 - 你可以通过一点数学来避免你的三向if

【讨论】:

我一直在寻找这个解决方案。谢谢解释!【参考方案2】:

标签呢?非常简单。

subText = [NSString stringWithFormat:@"%3d%%\t-\t%@",subPercent,subfactor];

【讨论】:

现在它在 100% i.imgur.com/1iKIpJI.png 上坏了如果使用 @"%4d%%\t- %@",也会在 10-99 数字上坏 您可能想查看您的代码。我添加了 2 个标签。你只有 1 个。你也有 3 个数字 (3d),现在你有 4 个 (4d) 第二个选项卡在连字符后添加多余的空格。使用 %3d 它适用于除 100 之外的所有数字。 另一种选择是制作 3 个 UILabel 而不是 1 个标签。这将保证你的位置 我知道。但必须是更好的解决方案。【参考方案3】:

为什么不使用三个不同的UILabel?我认为它会比这些“神奇”空间干净得多! 你要想象一下,如果你还有一些其他的词或者一些其他的数值,你还会使用这种方法吗?!

【讨论】:

【参考方案4】:

似乎这个问题与您不使用固定宽度字体时用于填充的空间宽度有关。如果您使用像 Courier 这样的固定宽度字体,您的代码可以正常工作(但 courier 很难看)。对于可变宽度字体,我发现您需要将 %4d 用于 2 位数字,将 %5d 用于一位数字。你可以这样做,

subText = [NSString stringWithFormat:@"%*d%% - %@", 6 - (int)[NSString stringWithFormat:@"%d",subpercent].length, sub percent, subfactor];

【讨论】:

以上是关于为啥字符串格式在 UILabel 中不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

在 UILabel 中覆盖“文本”在 iOS 6 中不起作用

UIlabel layer.cornerRadius在iOS 7.1中不起作用

UILabel 的 numberOfLines 在单元格中不起作用

设置 UILabel 对齐顶部在单元格中不起作用

“Italic”在Xcode -iOS中的UILabel中不起作用

为啥字符串本地化/国际化在 SwiftUI 中不起作用?