You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

iOS 18 SwiftUI中可变字体(Variable Fonts)设置轴参数后不生效的问题求助

iOS 18 SwiftUI中可变字体(Variable Fonts)设置轴参数后不生效的问题求助

我正在尝试在我的项目中使用可变字体,这是一个针对iOS 18的新项目,我在模拟器上进行测试。以下是我加载和注册可变字体的代码:

public enum VariableFont: String {
    case inter = "Inter"
    case geologica = "Geologica"
}

public enum GeologicaFontAxis: Int {
    case cursive = 258
    case shaerpness = 259
    case slant = 260
    case weight = 257
}

public extension Font {
    
    static func variableFont(
        _ font: VariableFont,
        size: CGFloat,
        axis: [Int: Int]
    ) -> Font {
        Font(UIFont(descriptor: .init(
            fontAttributes: [
                .name: font.rawValue,
                kCTFontVariationAttribute as UIFontDescriptor.AttributeName: axis
            ]
        ), size: size))
    }
    
    static func geologica(size: CGFloat, axis: [GeologicaFontAxis: Int]) -> Font {
        let tuples = axis.map({ (key: GeologicaFontAxis, value: Int) in
            return (key.rawValue, value)
        })
        let axis: [Int: Int] = .init(uniqueKeysWithValues: tuples)
        return variableFont(.geologica, size: size, axis: axis)
    }
    
    static func registerFont(_ fontName: String) {
        guard let fontURL = Bundle.module.url(forResource: fontName, withExtension: "ttf") else {
            print("Failed to locate font in bundle")
            return
        }
        guard let fontDataProvider = CGDataProvider(url: fontURL as CFURL) else {
            print("Failed to create CGDataProvider from fontURL")
            return
        }
        guard let font = CGFont(fontDataProvider) else {
            print("Failed to create CGFont from data provider")
            return
        }
        if isDebugMode(), let variationAxes = font.variationAxes {
            let axes = variationAxes as NSArray
            for axe in axes {
                dump(axe)
            }
        }
        var error: Unmanaged<CFError>?
        guard CTFontManagerRegisterGraphicsFont(font, &error) else {
            print("Error registering font: \(String(describing: error?.takeUnretainedValue()))")
            return
        }
        print("Font registered successfully")
    }
}

请注意:原代码中GeologicaFontAxis枚举里的shaerpness存在拼写错误,正确应为sharpness,这可能不会直接导致功能失效,但建议修正以保持代码可读性。

我使用fonttools获取了我正在使用的“Geologica”字体的轴信息:

<!-- Weight -->
<Axis>
  <AxisTag>wght</AxisTag>
  <Flags>0x0</Flags>
  <MinValue>100.0</MinValue>
  <DefaultValue>100.0</DefaultValue>
  <MaxValue>900.0</MaxValue>
  <AxisNameID>257</AxisNameID>
</Axis>

<!-- Cursive -->
<Axis>
  <AxisTag>CRSV</AxisTag>
  <Flags>0x0</Flags>
  <MinValue>0.0</MinValue>
  <DefaultValue>0.0</DefaultValue>
  <MaxValue>1.0</MaxValue>
  <AxisNameID>258</AxisNameID>
</Axis>

<!-- Sharpness -->
<Axis>
  <AxisTag>SHRP</AxisTag>
  <Flags>0x0</Flags>
  <MinValue>0.0</MinValue>
  <DefaultValue>0.0</DefaultValue>
  <MaxValue>100.0</MaxValue>
  <AxisNameID>259</AxisNameID>
</Axis>

<!-- Slant -->
<Axis>
  <AxisTag>slnt</AxisTag>
  <Flags>0x0</Flags>
  <MinValue>-12.0</MinValue>
  <DefaultValue>0.0</DefaultValue>
  <MaxValue>0.0</MaxValue>
  <AxisNameID>260</AxisNameID>
</Axis>

所以GeologicaFontAxis枚举中的数字就是来自这里。看起来代码是可以运行的,我能看到“Font registered successfully”的日志,并且运行应用时轴数据也能正确打印:

▿ 4 key/value pairs #0
  ▿ (2 elements)
    - key: kCGFontVariationAxisName #1
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: Weight #2
      - super: NSString
        - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisMinValue #3
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: 100 #4
      - super: NSNumber
        - super: NSValue
          - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisMaxValue #5
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: 900 #6
      - super: NSNumber
        - super: NSValue
          - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisDefaultValue #7
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: 100 #4
▿ 4 key/value pairs #0
  ▿ (2 elements)
    - key: kCGFontVariationAxisName #1
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: Cursive #2
      - super: NSString
        - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisMinValue #3
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: 0 #4
      - super: NSNumber
        - super: NSValue
          - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisMaxValue #5
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: 1 #6
      - super: NSNumber
        - super: NSValue
          - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisDefaultValue #7
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: 0 #4
▿ 4 key/value pairs #0
  ▿ (2 elements)
    - key: kCGFontVariationAxisName #1
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: Sharpness #2
      - super: NSString
        - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisMinValue #3
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: 0 #4
      - super: NSNumber
        - super: NSValue
          - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisMaxValue #5
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: 100 #6
      - super: NSNumber
        - super: NSValue
          - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisDefaultValue #7
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: 0 #4
▿ 4 key/value pairs #0
  ▿ (2 elements)
    - key: kCGFontVariationAxisName #1
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: Slant #2
      - super: NSString
        - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisMinValue #3
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: -12 #4
      - super: NSNumber
        - super: NSValue
          - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisMaxValue #5
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: 0 #6
      - super: NSNumber
        - super: NSValue
          - super: NSObject
  ▿ (2 elements)
    - key: kCGFontVariationAxisDefaultValue #7
      - super: __NSCFString
        - super: NSMutableString
          - super: NSString
            - super: NSObject
    - value: 0 #6
Font registered successfully

“Geologica”字体有四个轴,日志也正确显示了这些信息。我在SwiftUI中是这样使用它的:

let titleFont = Font.geologica(
    size: 24,
    axis: [GeologicaFontAxis.weight: 600]
)

Text("modern-airlines", bundle: .module)
    .font(titleFont)
    .textCase(.uppercase)
    .padding(.top, 12)

但无论是在模拟器还是预览中,字体的轴参数都没有生效。我该怎么解决这个问题?这会不会是模拟器或预览的bug?

参考资料

  • 可变字体在SwiftUI中的使用实践
  • 利用fonttools分析可变字体轴属性

备注:内容来源于stack exchange,提问作者Olcay Ertaş

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.15 09:04:35