SwiftUI中如何让自定义字体像系统字体一样随屏幕动态缩放?
解决SwiftUI自定义字体与系统字体一致的响应式缩放问题
要让自定义字体和系统字体拥有完全一致的响应式缩放(适配不同设备屏幕+动态类型),核心是对齐系统字体的尺寸计算逻辑,以下是具体方案:
方案1:基于系统文本样式的基准尺寸
系统字体的size:参数本质是对应文本样式的缩放基准,而自定义字体直接传固定size:是绝对点值,无法自动适配屏幕缩放。通过获取系统样式的实际渲染尺寸,再传递给自定义字体,就能对齐缩放行为:
Text("Custom Font") .font(.custom( "BrittiSansTrial-Semibold", size: UIFont.preferredFont(forTextStyle: .body).pointSize, relativeTo: .body ))
UIFont.preferredFont(forTextStyle: .body)会自动返回当前设备(含屏幕缩放、动态类型设置)下.body样式的实际点尺寸- 搭配
relativeTo: .body可同时支持系统动态类型调整(用户手动放大/缩小系统字体)
如果你的系统字体代码是.system(size:14, weight:.semibold),说明14是.body样式的基准尺寸,直接用上面的代码就能完全匹配缩放效果。
方案2:手动适配屏幕缩放因子
如果需要自定义基准尺寸,可通过设备屏幕缩放因子计算最终尺寸,确保自定义字体和系统字体的物理大小一致:
先封装一个扩展简化调用:
extension View { func customFont(_ name: String, size: CGFloat, relativeTo style: Font.TextStyle) -> some View { // 获取屏幕缩放因子,将逻辑点转换为匹配系统缩放的点值 let scaledSize = size * UIScreen.main.scale return self.font(.custom(name, size: scaledSize, relativeTo: style)) } }
使用方式:
Text("Custom Font") .customFont("BrittiSansTrial-Semibold", size: 14, relativeTo: .body)
前置验证:确保自定义字体正确导入
如果缩放仍不一致,先检查字体是否正确集成:
- 字体文件已添加到项目,且勾选了对应Target的"Target Membership"
- Info.plist中添加
Fonts provided by application键,填入完整字体文件名(如BrittiSansTrial-Semibold.otf) - 通过以下代码验证字体名称是否正确(打印的名称需和代码中使用的完全一致):
for family in UIFont.familyNames { print(family) for name in UIFont.fontNames(forFamilyName: family) { print(" \(name)") } }
内容的提问来源于stack exchange,提问作者dex
相关产品推荐
相关产品推荐

