How can I set NSTableView column to use monospaced numbers?

◇◆丶佛笑我妖孽 提交于 2019-12-08 18:52:53

问题


El Capitan introduced San Francisco system font, which has proportional digits by default.

This makes numbers in table columns look jagged and hard to compare:

I'd like to enable fixed-width numbers option for the font, but keep using the default system font and keep backwards compatibility with earlier versions of OS X.

In Interface Builder selecting font > Font Panel > Typography > Monospaced Numbers does not affect the font (XIB file remains unchanged).

What's the right way to set monospaced numbers in OS X table view columns? (I suspect IB is unusable for this, so a programmatic solution is OK too).


回答1:


Just use +[NSFont monospacedDigitSystemFontOfSize:weight:] when it's available. It's new in 10.11, but still not in the NSFont docs. It's in the headers and was discussed in the WWDC 2015 videos. So, something like:

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



回答2:


Treat the following as pseudo-code, quickly done, not throughly tested, etc.

Given an NSFont which represents a font which has monospaced numbers as a feature the following method will produce another NSFont with that feature selected:

- (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;
}

You can use this, say, to take the current font of a UI element and convert it to one with monospace numbers.

HTH

Variant for Swift

Assuming res is the NSTextField with the number to display:

let origDesc = CTFontCopyFontDescriptor(res.font!)
let monoDesc = CTFontDescriptorCreateCopyWithFeature(origDesc, kNumberSpacingType, kMonospacedNumbersSelector)
let monoFont = CTFontCreateWithFontDescriptor(monoDesc, res.font!.pointSize, nil)
res.font = monoFont



回答3:


Here's a Swift extension that gives you a monospaced digits font with high legibility.

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
    }
}




回答4:


In my experience, the "font panel" functionality isn't well defined and I usually just ignore it whenever I'm messing with a XIB or Storyboard.

What should work is to go back to that "Font" attribute in the Text Field Cell attributes inspector and then select "User Fixed Pitch" from the Font drop down menu (the choice should automatically default to size 11).

If you bump the font size up a point, it'll magically switch to Monaco (the default fixed width font).



来源:https://stackoverflow.com/questions/33954528/how-can-i-set-nstableview-column-to-use-monospaced-numbers

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!