【问题标题】:Displaying proportionally spaced numbers (instead of monospace / tabular) on iOS在 iOS 上显示按比例间隔的数字(而不是等宽/表格)
【发布时间】:2013-11-26 02:26:11
【问题描述】:

我通过将数字存储在 NSAttributedString 中并使用“drawAtPoint:”渲染来在 iOS 中渲染数字(针对 7 及以上)。我正在使用 Helvetica Neue。

我注意到像这样绘制的数字的位数不成比例 - 字形都具有相同的宽度。即使是细小的“1”也与“0”占用相同的空间。

测试证实了这一点:

for(NSInteger i=0; i<10; ++i)
{
  NSString *iString = [NSString stringWithFormat: @"%d", i];
  const CGSize iSize = [iString sizeWithAttributes: [self attributes]];
  NSLog(@"Size of %d is %f", i, iSize.width);
}

在其他地方:

-(NSDictionary *) attributes
{
  static NSDictionary * attributes;
  if(!attributes)
  {
    attributes = @{
                   NSFontAttributeName: [UIFont systemFontOfSize:11],
                   NSForegroundColorAttributeName: [UIColor whiteColor]
                   };
  }
  return attributes;
}

生成的字形都具有相同的宽度,均为 6.358 磅。

我可以打开一些渲染选项来启用比例数字字形吗?是否有另一种字体(理想情况下类似于 Helvetica Neue)支持比例数字字形(理想情况下是内置的)?还有什么?

谢谢。

【问题讨论】:

  • link 讨论了比例诗句“表格”(等宽的另一个术语)“数字”和“数字”的使用。通过使用该术语进行搜索,我在 iOS 7 字体渲染中找到了这个 link,我认为这会让我自己回答这个问题。完成后我会更新。
  • 这个来自 Apple 演示文稿的 pdf link 幻灯片提供了所需的代码。重要的是要知道要使用这些功能,您必须#import &lt;CoreText/CoreText.h&gt;:这是定义符号的地方。

标签: ios nsstring uifont uifontdescriptor


【解决方案1】:

iOS 7 允许您使用 UIFontDescriptor 实例指定字体。然后从描述符中获取UIFont 实例。

给定一个UIFontDescriptor,也可以通过使用[fontDescriptor fontDescriptorByAddingAttributes: attibutes]方法来获得它的定制,改变一些特征,其中attributes是一个NSDictionary字体属性。

Apple 在UIFontDescriptor reference 中记录属性。

从参考资料中,一个特定的字体描述符属性UIFontDescriptorFeatureSettingsAttribute 允许您提供“表示非默认字体功能设置的字典数组。每个字典包含UIFontFeatureTypeIdentifierKeyUIFontFeatureSelectorIdentifierKey。”

UIFontFeatureTypeIdentifierKeys 和 UIFontFeatureSelectorIdentifierKeys 的文档位于 Apple's Font Registry documentation。这个pdf of slides of an Apple presentation涵盖了比例数字的具体情况,所以我只是取消了它。

此代码将采用现有的 UIFont 实例并返回具有比例数字的新实例:

// You'll need this somewhere at the top of your file to pull
// in the required constants.
#import <CoreText/CoreText.h>

…

UIFont *const existingFont = [UIFont preferredFontForTextStyle: UIFontTextStyleBody];
UIFontDescriptor *const existingDescriptor = [existingFont fontDescriptor];

NSDictionary *const fontAttributes = @{
 // Here comes that array of dictionaries each containing UIFontFeatureTypeIdentifierKey 
 // and UIFontFeatureSelectorIdentifierKey that the reference mentions.
 UIFontDescriptorFeatureSettingsAttribute: @[
     @{
       UIFontFeatureTypeIdentifierKey: @(kNumberSpacingType),
       UIFontFeatureSelectorIdentifierKey: @(kProportionalNumbersSelector)
      }]
 };

UIFontDescriptor *const proportionalDescriptor = [existingDescriptor fontDescriptorByAddingAttributes: fontAttributes];
UIFont *const proportionalFont = [UIFont fontWithDescriptor: proportionalDescriptor size: [existingFont pointSize]];

如果您愿意,可以将其添加为 UIFont 上的一个类别,等等。

编辑说明:感谢 Chris Schwerdt 的改进。

【讨论】:

  • +1 不要忘记为这些常量导入 CoreText。
  • 谢谢马丁,我会修改代码以添加它,因为它最初让我摸不着头脑!
  • UIFontFeatureTypeIdentifierKeyUIFontFeatureSelectorIdentifierKey 的值可以在SFNTLayoutTypes.h 中找到,它进一步引用了Apple's Font Registry documentation
  • 另外,您可以删除kCharacterAlternativesType 键。我相信它在那个时候的格式化示例中被用来用圆角冒号替换方形冒号,并且不影响数字间距。
  • 此选项仅在您使用支持此功能的字体时才有效。如果您使用的是自定义字体,这可能不起作用。可以通过以下方式检查字体支持的选项:NSLog(@"%@", CTFontCopyFeatures ( ( __bridge CTFontRef ) myFont ));
猜你喜欢
  • 1970-01-01
  • 2021-12-01
  • 2015-08-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-02-08
  • 2013-03-06
相关资源
最近更新 更多