SwiftUI:如何设置空Text视图的高度为单行高度
解决Text为空时框架塌陷的问题
要让带边框的框架在Text为空时保持固定高度,核心是给frame设置最小高度,这个高度要匹配.xxxLarge动态字体的行高加上上下padding的总和。
具体实现步骤:
- 计算
.xxxLarge动态字体对应的行高,再加上上下各6的padding,得到框架的最小高度。 - 给
frame添加minHeight参数,确保空Text时框架不会塌陷。 - 移除重复的边框设置(原代码同时用了
border和overlay的stroke,保留一个即可)。
修改后的代码:
// 提前计算最小高度 private let minFrameHeight: CGFloat = { // 获取xxxLarge动态字体的行高 let traitCollection = UITraitCollection(preferredContentSizeCategory: .accessibilityExtraExtraExtraLarge) let font = UIFont.preferredFont(forTextStyle: .body, compatibleWith: traitCollection) // 加上上下各6的padding return font.lineHeight + 12 }() // 视图代码 Text(filtreString) .padding(6) .dynamicTypeSize(.xxxLarge) .frame(maxWidth: .infinity, minHeight: minFrameHeight) .background(Color("fondbleu")) .cornerRadius(20.0) .overlay( RoundedRectangle(cornerRadius: 20).stroke(.black, lineWidth: 1) )
原理说明:
- 通过
UITraitCollection指定.accessibilityExtraExtraExtraLarge(对应SwiftUI的.xxxLarge动态字体),获取对应的系统字体行高。 - 加上上下padding的总和(6*2=12),确保框架高度和有文本时一致。
- 设置
minHeight后,无论Text是否为空,框架都会保持这个最小高度,同时maxWidth: .infinity保证宽度充满父视图。
替代方案(纯SwiftUI方式):
如果不想用UIKit的API,可以用一个隐藏的占位Text来获取高度,通过PreferenceKey传递:
struct TextHeightPreferenceKey: PreferenceKey { static var defaultValue: CGFloat = 0 static func reduce(value: inout CGFloat, nextValue: () -> CGFloat) { value = nextValue() } } struct YourView: View { @State private var textHeight: CGFloat = 0 @State var filtreString: String = "" var body: some View { Text(filtreString) .padding(6) .dynamicTypeSize(.xxxLarge) .frame(maxWidth: .infinity, minHeight: textHeight) .background(Color("fondbleu")) .cornerRadius(20.0) .overlay( RoundedRectangle(cornerRadius: 20).stroke(.black, lineWidth: 1) ) // 添加隐藏的占位Text获取高度 .background( Text(" ") .padding(6) .dynamicTypeSize(.xxxLarge) .hidden() .background( GeometryReader { proxy in Color.clear .preference(key: TextHeightPreferenceKey.self, value: proxy.size.height) } ) ) .onPreferenceChange(TextHeightPreferenceKey.self) { textHeight = $0 } } }
这个方案完全用SwiftAPI实现,通过隐藏的Text获取满字体高度,再应用到目标框架的minHeight,同样能解决空Text时框架塌陷的问题。
内容的提问来源于stack exchange,提问作者Simon W
相关产品推荐
相关产品推荐

