如何设置NSTableView列使用等宽数字?

7

El Capitan引入了旧金山系统字体,默认情况下具有比例数字。

这使得表格列中的数字看起来锯齿状,难以比较:

all are 6-digit numbers

我想启用字体的等宽数字选项,但仍然使用默认系统字体,并保持与OS X早期版本的向后兼容。

在Interface Builder中选择字体>字体面板>排版>等宽数字不会影响字体(XIB文件保持不变)。

useless panel

在OS X表视图列中设置等宽数字的正确方法是什么?(我怀疑IB对此无用,因此编程解决方案也可以)。


你是如何填充这些单元格的?使用绑定还是使用NSTableViewDataSource中的某些内容(例如['tableView:objectValueForTableColumn:row:'](https://developer.apple.com/library/mac/documentation/Cocoa/Reference/ApplicationKit/Protocols/NSTableDataSource_Protocol/#//apple_ref/occ/intfm/NSTableViewDataSource/tableView:objectValueForTableColumn:row:))? - Michael Dautermann
@MichaelDautermann 我正在使用NSArrayController绑定。 - Kornel
我认为应该接受Johan的答案,因为它没有使用私有API。 - ctietze
4个回答

11

如果可用,只需使用 +[NSFont monospacedDigitSystemFontOfSize:weight:]。它在10.11中是新功能,但仍未包含在NSFont文档中。它在头文件中,并在WWDC 2015视频中有讨论。因此,类似以下内容:

if ([NSFont respondsToSelector:@selector(monospacedDigitSystemFontOfSize:weight:)])
    textField.font = [NSFont monospacedDigitSystemFontOfSize:textField.font.pointSize weight:NSFontWeightRegular];

5
这里有一个Swift扩展,可以提供具有高可读性的等宽数字字体。
extension NSFont {
    var legibleNumbersVariant: NSFont {
        let features = [
            [NSFontFeatureTypeIdentifierKey: kNumberSpacingType,
             NSFontFeatureSelectorIdentifierKey: kMonospacedNumbersSelector],
            [NSFontFeatureTypeIdentifierKey: kStylisticAlternativesType,
             NSFontFeatureSelectorIdentifierKey: kStylisticAltSixOnSelector]
        ]
        let descriptor = fontDescriptor.addingAttributes([NSFontFeatureSettingsAttribute: features])
        return NSFont(descriptor: descriptor, size: pointSize) ?? self
    }
}

Comparison


4

请将以下内容视为伪代码,快速完成,未经彻底测试等。

给定一个表示具有等宽数字特征的字体的NSFont,以下方法将产生另一个选择了该特征的NSFont

- (NSFont *) newMonospaceNumbersFont:(NSFont *)font
{
   CTFontDescriptorRef origDesc = CTFontCopyFontDescriptor((__bridge CTFontRef)font);
   CTFontDescriptorRef monoDesc = CTFontDescriptorCreateCopyWithFeature(origDesc, (__bridge CFNumberRef)@(kNumberSpacingType), (__bridge CFNumberRef)@(kMonospacedNumbersSelector));
   CFRelease(origDesc);
   CTFontRef monoFont = CTFontCreateWithFontDescriptor(monoDesc, font.pointSize, NULL);
   CFRelease(monoDesc);
   return (__bridge_transfer NSFont *)monoFont;
}

你可以使用这个方法,例如将UI元素的当前字体转换为具有等宽数字的字体。
希望对你有所帮助。
Swift变量:
假设“res”是要显示数字的“NSTextField”:
let origDesc = CTFontCopyFontDescriptor(res.font!)
let monoDesc = CTFontDescriptorCreateCopyWithFeature(origDesc, kNumberSpacingType, kMonospacedNumbersSelector)
let monoFont = CTFontCreateWithFontDescriptor(monoDesc, res.font!.pointSize, nil)
res.font = monoFont

2
根据我的经验,“字体面板”功能没有很好的定义,每当我在操作XIB或Storyboard时,我通常都会忽略它。
应该有效的方法是返回到文本字段单元格属性检查器中的“字体”属性,然后从字体下拉菜单中选择“用户固定间距”(选择应自动默认为11号字体大小)。

Choose your font this way

如果你将字体大小增加一个点,它会神奇地切换到 Monaco(默认的等宽字体)。

1
我正在寻找一种解决方案,可以适当地使用旧金山字体(带有单数字选项)/Helvetica/Lucida Grande来适配系统,而使用Monaco则不够理想。 - Kornel

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