SwiftUI中如何同步两个Text对象的字体大小并实现最大适配?
解决方案
要实现两个Text使用相同的最大适配字号,且各自限制在屏幕半宽容器内单行完整显示,核心思路是先分别计算两个文本在半宽容器内的最大可容纳字号,再取两者的最小值作为统一字号。以下是具体实现:
完整代码
struct ScoreView: View { let scoreA: String = "5" let scoreB: String = "234" // 计算文本在指定宽度内单行显示的最大字号(二分法优化性能) private func maxFontSize(for text: String, in width: CGFloat) -> CGFloat { let testText = Text(text) var low: CGFloat = 1 var high: CGFloat = 1000 var bestSize: CGFloat = 1 while low <= high { let mid = (low + high) / 2 let textSize = testText.font(.system(size: mid)).sizeThatFit(CGSize(width: width, height: .infinity)) if textSize.width <= width { bestSize = mid low = mid + 1 } else { high = mid - 1 } } return bestSize } var body: some View { GeometryReader { geo in let halfScreenWidth = geo.size.width / 2 // 分别计算两个文本的最大适配字号 let maxSizeForA = maxFontSize(for: scoreA, in: halfScreenWidth) let maxSizeForB = maxFontSize(for: scoreB, in: halfScreenWidth) // 取最小值作为统一字号 let unifiedFontSize = min(maxSizeForA, maxSizeForB) HStack(spacing: 0) { Text(scoreA) .font(.system(size: unifiedFontSize)) .lineLimit(1) .frame(width: halfScreenWidth, maxHeight: .infinity) .background(.red.opacity(0.3)) Text(scoreB) .font(.system(size: unifiedFontSize)) .lineLimit(1) .frame(width: halfScreenWidth, maxHeight: .infinity) .background(.blue.opacity(0.3)) } } } }
关键说明
字号计算逻辑:
- 通过
GeometryReader获取父容器的总宽度,平分后得到每个Text的可用宽度。 - 用二分法实现高效的字号计算:从1到1000的字号范围中,快速找到文本刚好能在指定宽度内单行显示的最大字号,比逐次递减字号的方式性能更优。
- 通过
统一字号应用:
- 取两个文本各自最大适配字号的最小值,确保两个
Text使用相同字号时,都能在各自的半宽容器内完整显示,不会出现截断。
- 取两个文本各自最大适配字号的最小值,确保两个
容器限制:
- 每个
Text的frame固定为半屏幕宽度,确保严格限制在自身区域内,避免布局溢出。
- 每个
原代码问题分析
原代码中两个Text各自独立使用minimumScaleFactor缩放,由于"5"的字符长度远短于"234",其最终缩放比例更小、字号更大,无法实现两者字号统一的要求。新方案通过预计算统一字号,从根源上解决了这个问题。
内容的提问来源于stack exchange,提问作者soleil
相关产品推荐
相关产品推荐

