8

我通过将数字存储在 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)支持比例数字字形(理想情况下是内置的)?还要别的吗?

谢谢你。

4

1 回答 1

18

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

给定 aUIFontDescriptor也可以通过使用字体属性的[fontDescriptor fontDescriptorByAddingAttributes: attibutes]where attributesis an方法来获得改变某些特征的自定义。NSDictionary

Apple 记录了UIFontDescriptor参考中的属性。

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

UIFontFeatureTypeIdentifierKeys 和UIFontFeatureSelectorIdentifierKeys 的文档在Apple的 Font Registry 文档中。比例数字的具体情况在这个Apple 演示文稿幻灯片的 pdf 中进行了介绍,所以我只是取消了它。

此代码将采用现有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 的改进。

于 2013-11-14T11:31:05.253 回答