SwiftUI自定义字体如何实现bold、italics等样式的链式修饰符调用
这个需求完全可以实现,这里提供两种生产环境常用的实现方案:
方案1:全版本兼容的中间层封装方案(推荐)
我们可以通过封装一个自定义的字体配置结构体,存储字体的基础信息,给结构体加链式字重方法,完全避开SwiftUI Font无法读取属性的限制,兼容所有支持SwiftUI的iOS版本。
实现代码如下:
// 自定义字体配置结构体 struct CustomFontConvertible { /// 基础字体族名(不含字重后缀) let baseName: String /// 字体大小 let size: CGFloat /// 绑定的动态类型样式,用于动态缩放 let relativeTo: Font.TextStyle } // 给结构体加链式字重方法 extension CustomFontConvertible { /// 转普通字重的SwiftUI Font func font() -> Font { .custom(baseName, size: size, relativeTo: relativeTo) } /// 转半粗体的SwiftUI Font func semibold() -> Font { .custom("\(baseName)-SemiBold", size: size, relativeTo: relativeTo) } /// 可按需扩展bold、medium、light等其他字重 func bold() -> Font { .custom("\(baseName)-Bold", size: size, relativeTo: relativeTo) } } // 扩展Font定义你的静态字体属性 extension Font { static var acBody1: CustomFontConvertible { .init(baseName: "SuisseIntl", size: 17, relativeTo: .body) } }
使用方式完全符合你的预期:
// 普通字重 Font.acBody1.font() // 半粗体 Font.acBody1.semibold() // 粗体 Font.acBody1.bold()
如果不想在普通字体调用时加.font(),可以额外给Font加一层对应的静态属性:
extension Font { static let acBody1Regular: Font = acBody1.font() }
方案2:系统API解析方案(iOS16+)
iOS16及以上系统提供了UIFont从SwiftUI.Font直接转换的初始化方法,可以读取到现有Font的字体名、大小等属性,直接实现Font的semibold扩展:
import UIKit extension Font { @available(iOS 16.0, *) func semibold() -> Font { guard let uiFont = UIFont(font: self) else { return self } // 适配你的字体命名规则,这里默认是族名+半粗体后缀 let semiboldFontName = "\(uiFont.familyName)-SemiBold" let textStyle = uiFont.textStyle.map { Font.TextStyle($0) } ?? .body return .custom(semiboldFontName, size: uiFont.pointSize, relativeTo: textStyle) } }
这个方案不需要修改原有Font静态属性的定义,缺点是仅支持iOS16及以上系统,低版本系统无法使用。
内容的提问来源于stack exchange,提问作者RyJ
相关产品推荐
相关产品推荐

