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

SwiftUI中Google自定义字体文字截断及动态适配问题求解

SwiftUI自定义Google Fonts字符截断问题解决方案

问题概述

在SwiftUI中使用Google Fonts提供的Allura-Regular、Courgette-Regular、MrDafoe-Regular、ShadowsIntoLightTwo-Regular、SourceSansPro-Regular自定义字体时,带有高度的字符(如D、H、J、I等)出现截断情况。

已尝试的无效操作

  • 设置frame为maxWidth(.infinity)并调整高度
  • 添加padding及trailing方向内边距
  • 使用.fixedSize(horizontal: true, vertical: false)和.scaledToFit()
  • 新建空白SwiftUI项目测试问题仍然存在

关键观察

  • 自定义字体以UIFont形式应用于UIKit的UILabel时显示正常
  • 以SwiftUI.Font形式使用时出现字符截断
  • 集成自定义UILabelView(UIViewRepresentable)到SwiftUI代码中,问题依旧存在

需求

  • 标签随字符数量增加动态调整字号
  • 单行适配视图宽度
  • 项目最低部署版本为iOS 15

解决方案

方案1:优化SwiftUI Text的配置

SwiftUI的Text对部分自定义字体的基线、 ascent/descent 计算存在偏差,可通过以下调整修复:

  1. 使用.custom(_:size:relativeTo:)方法指定字体,帮助SwiftUI正确计算文本容器
  2. 添加垂直内边距预留字符高度空间
  3. 调整minimumScaleFactor为合理值,确保缩放逻辑正常

修改后的SwiftUI代码片段:

HStack(spacing: 8) {
    Spacer()
    Text(signText)
        .lineLimit(1)
        .allowsTightening(true)
        .minimumScaleFactor(0.25)
        // 替换原.font(font),用custom方法并指定relativeTo参数
        .font(.custom("Allura-Regular", size: 100, relativeTo: .title)) 
        .padding(.vertical, 8) // 增加垂直内边距避免字符被截断
        .frame(maxWidth: .infinity, alignment: .center)
    
    Spacer()
    if !signText.isEmpty {
        Button(action: {
            isSignSheetPresented = true
        }, label: {
            Image("edit")
                .renderingMode(.template)
                .frame(idealWidth: 44)
                .foregroundColor(Color(CanopyColor.primary.color))
        })
    }
}
.padding(16)
.frame(maxWidth: .infinity, idealHeight: 150, alignment: .center )
.background(Color(red: 0.98, green: 0.98, blue: 0.98))
.cornerRadius(4)
.overlay(
  RoundedRectangle(cornerRadius: 4)
    .inset(by: 0.5)
    .stroke(Color(red: 0.87, green: 0.87, blue: 0.87), lineWidth: 1) 
)

方案2:修复UIViewRepresentable的UILabel配置

原UILabelView添加了固定宽度约束,导致无法自适应父视图宽度,同时需要调整内容优先级确保布局正确:

修改后的UILabelView代码:

struct UILabelView: UIViewRepresentable {
    var text: String
    var font: UIFont
    
    func makeUIView(context: Context) -> UILabel {
        let label = UILabel()
        label.font = font
        label.text = text
        label.numberOfLines = 1
        label.textAlignment = .center
        label.backgroundColor = .clear
        label.adjustsFontSizeToFitWidth = true
        label.minimumScaleFactor = 0.25
        label.allowsDefaultTighteningForTruncation = true
        label.translatesAutoresizingMaskIntoConstraints = false
        
        // 移除固定宽度约束,设置内容优先级让label自适应父视图
        label.setContentHuggingPriority(.defaultLow, for: .horizontal)
        label.setContentCompressionResistancePriority(.defaultHigh, for: .horizontal)
        
        return label
    }
    
    func updateUIView(_ uiView: UILabel, context: Context) {
        uiView.text = text
        uiView.font = font
        uiView.textAlignment = .center
    }
}

额外检查项

  • 确认Info.plist中已添加Fonts provided by application条目,且字体文件名与注册名完全一致
  • 检查字体文件是否正确导入项目(勾选"Add to targets")

内容的提问来源于stack exchange,提问作者SwiftCoderJr

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 16:33:19