UIFont等距数字+小写

时间:2018-08-13 18:29:21

标签: ios swift uikit uifont uifontdescriptor

我正在尝试创建具有以下属性的UIFont

  • 大写小写字母
  • 小写小写字母
  • 等距数字

我正在使用系统字体(San Francisco),它支持所有这些功能。
据我所知,唯一的方法是使用多个UIFontDescriptor

这是我正在使用的代码:

extension UIFont {

    var withSmallCaps: UIFont {
        let upperCaseFeature = [
            UIFontDescriptor.FeatureKey.featureIdentifier : kUpperCaseType,
            UIFontDescriptor.FeatureKey.typeIdentifier : kUpperCaseSmallCapsSelector
        ]
        let lowerCaseFeature = [
            UIFontDescriptor.FeatureKey.featureIdentifier : kLowerCaseType,
            UIFontDescriptor.FeatureKey.typeIdentifier : kLowerCaseSmallCapsSelector
        ]
        let features = [upperCaseFeature, lowerCaseFeature]
        let smallCapsDescriptor = self.fontDescriptor.addingAttributes([UIFontDescriptor.AttributeName.featureSettings : features])

        return UIFont(descriptor: smallCapsDescriptor, size: pointSize)
    }

    var withMonospacedDigits: UIFont {
        let monospacedDigitsFeature = [
            UIFontDescriptor.FeatureKey.featureIdentifier : kNumberSpacingType,
            UIFontDescriptor.FeatureKey.typeIdentifier : kMonospacedNumbersSelector
        ]
        let monospacedDigitsDescriptor = self.fontDescriptor.addingAttributes([UIFontDescriptor.AttributeName.featureSettings : [monospacedDigitsFeature]])

        return UIFont(descriptor: monospacedDigitsDescriptor, size: pointSize)
    }
}

我应该能够使用此行代码获得具有前面提到的所有特征的字体:

let font = UIFont.systemFont(ofSize: 16, weight: .regular).withSmallCaps.withMonospacedDigits
// OR
let font = UIFont.monospacedDigitSystemFont(ofSize: 16, weight: .regular).withSmallCaps

但是由于某些原因,它不起作用。我不能同时具有小写大写字母的字体具有等宽数字。

我在做什么错了?

2 个答案:

答案 0 :(得分:0)

有关更多详细信息,请查看reference文档。 我建议为所有字形(但数字)使用带有小写大写字母的属性字符串,并为等距数字使用另一种字体。这是一些示例代码:

let monoSpacedDigits = UIFont.systemFont(ofSize: 13, weight: .medium).withMonospacedDigits
let smallCaps = UIFont.systemFont(ofSize: 16, weight: .regular).withSmallCaps



let attributedString = NSMutableAttributedString(string: """
H3ll0 7here
1111111111
2222222222
3333333333
4444444444
5555555555
6666666666
7777777777
8888888888
9999999999
0000000000
""", attributes: [NSAttributedStringKey.font : smallCaps])

do {
    let regex = try NSRegularExpression(pattern: "[0-9]")
    let range = NSRange(0..<attributedString.string.utf16.count)
    let matches = regex.matches(in: attributedString.string, range: range)
    for match in matches.reversed() {
        attributedString.addAttribute(NSAttributedStringKey.font, value: monoSpacedDigits, range: match.range)
    }
} catch {
    // Do error processing here...
    print(error)
}

myLabel.attributedText = attributedString

我使用13号字体和中等重量,以使等距数字看起来与小写字母尽可能相似。

答案 1 :(得分:0)

由于reference document链接的@Carpsen90,我弄清楚了为什么它不起作用。

Number Spacing功能似乎是专有

如文档中所述:

  

功能分为“独占”和“非独占”。这表明是否可以一次选择给定要素类型内的几个不同选择器。因此,可以同时打开普通和罕见连字,而不可能同时显示垂直和对角线的给定分数。

因此同时具有两个等宽数字和小写字母功能是不可能的。


编辑:

我误读了文档。该功能的选择器是排他的。但不是全部功能。因此应该有可能。