【问题标题】:Cannot create Small Caps Selector on iOS 13无法在 iOS 13 上创建小型大写字母选择器
【发布时间】:2020-01-29 17:04:40
【问题描述】:

下面的这段代码使我能够在 iOS 12 上创建小型大写字母。但是在 iOS 13 上它已停止工作。

iOS 12 日志

.SFUIDisplay-Semibold
.SFUIDisplay-Semibold

iOS 13 日志

.SFUI-Semibold
TimesNewRomanPSMT

SFUI 字体似乎至少在 iOS 13 中改名了,但它是否也放弃了对小型大写字母的支持?

let font = UIFont.systemFont(ofSize: 20, weight: .semibold)
print(font.fontName)

let settings = [[UIFontDescriptor.FeatureKey.featureIdentifier: kLowerCaseType,
                 UIFontDescriptor.FeatureKey.typeIdentifier: kLowerCaseSmallCapsSelector]]

let attributes: [UIFontDescriptor.AttributeName: AnyObject] = [UIFontDescriptor.AttributeName.featureSettings: settings as AnyObject,
                                                               UIFontDescriptor.AttributeName.name: font.fontName as AnyObject]

let smallCapsFont = UIFont(descriptor: UIFontDescriptor(fontAttributes: attributes), size: 20)
print(smallCapsFont.fontName)

【问题讨论】:

    标签: ios swift xcode ios13 ios12


    【解决方案1】:

    您的代码总是错误的。您首先创建一个字体,然后通过字体的 name 从中派生一个字体描述符:

    let font = UIFont.systemFont(ofSize: 20, weight: .semibold)
    let settings = [
        [UIFontDescriptor.FeatureKey.featureIdentifier: kLowerCaseType,
        UIFontDescriptor.FeatureKey.typeIdentifier: kLowerCaseSmallCapsSelector]
    ]
    let attributes: [UIFontDescriptor.AttributeName: AnyObject] = [
        UIFontDescriptor.AttributeName.featureSettings: settings as AnyObject,
        UIFontDescriptor.AttributeName.name: font.fontName as AnyObject // ** NO!
    ]
    let smallCapsFont = UIFont(descriptor: UIFontDescriptor(fontAttributes: attributes), size: 20)
    

    那是从来没有正确的。您应该直接从字体本身派生字体描述符。这就是您的代码应该始终 的样子。它在 iOS 12 中运行,现在可以运行:

    let font = UIFont.systemFont(ofSize: 20, weight: .semibold)
    let settings = [
        [UIFontDescriptor.FeatureKey.featureIdentifier: kLowerCaseType,
        UIFontDescriptor.FeatureKey.typeIdentifier: kLowerCaseSmallCapsSelector]
    ]
    let desc = font.fontDescriptor.addingAttributes([.featureSettings:settings])
    let smallCapsFont = UIFont(descriptor: desc, size: 0)
    

    【讨论】:

    • 我一直在用几乎相同的代码来解决这个问题,在用你的代码进行测试后,我发现.featureIdentifier.typeIdentifier 混淆了。谢谢!
    • @Andreas 他们是可怕的名字!我对此有一个错误。
    • 很高兴知道我并不孤单。您不会碰巧知道如何从小型股的影响中排除数字吗? (问:stackoverflow.com/q/65041221/220820
    • @Andreas 你只需要使用不同的“字体”(即不同的变体)。
    【解决方案2】:

    像这样的系统字体现在可以使用“点”/. 表示法(即使像您的 font.fontName 示例那样重新创建它们时)可以参考:

    https://developer.apple.com/videos/play/wwdc2019/227/

    从 iOS 13 开始,您可以使用新的枚举 UIFontDescriptor.SystemDesignregularroundedserifmonospaced

    如何在 Swift 中使用描述符创建字体的示例(请参阅我如何使用 design 参数):

    extension UIFont {
    
        convenience init?(
            style: UIFont.TextStyle,
            weight: UIFont.Weight = .regular,
            design: UIFontDescriptor.SystemDesign = .default) {
    
            guard let descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: style)
                .addingAttributes([UIFontDescriptor.AttributeName.traits: [UIFontDescriptor.TraitKey.weight: weight]])
                .withDesign(design) else {
                    return nil
            }
            self.init(descriptor: descriptor, size: 0)
        }
    }
    
    

    【讨论】:

      【解决方案3】:

      从@Ash Camerons 的回答中汲取灵感,这里是允许您应用小型大写字母的更新代码

      请注意,这仅适用于 iOS 13+,但您可以选择为 iOS 13 及更高版本添加 .withDesign(systemDesign) 行。

      let pointSize: CGFloat = 20
      let weight: UIFont.Weight = .semibold
      let systemDesign: UIFontDescriptor.SystemDesign = .default
      
      let settings = [[UIFontDescriptor.FeatureKey.featureIdentifier: kLowerCaseType,
                       UIFontDescriptor.FeatureKey.typeIdentifier: kLowerCaseSmallCapsSelector]]
      
      let descriptor = UIFontDescriptor.preferredFontDescriptor(withTextStyle: .callout)
              .addingAttributes([UIFontDescriptor.AttributeName.traits: [UIFontDescriptor.TraitKey.weight: weight]])
              .addingAttributes([UIFontDescriptor.AttributeName.featureSettings: settings])
              .addingAttributes([UIFontDescriptor.AttributeName.size: pointSize])
              .withDesign(systemDesign)
      
      let font = UIFont(descriptor: descriptor!, size: pointSize)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-02-09
        • 1970-01-01
        • 1970-01-01
        • 2020-08-04
        • 2015-04-18
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多