ScrollView中UIViewRepresentable封装的UITextView渲染异常求助
问题:SwiftUI封装UITextView无法自适应高度完整显示文本
在SwiftUI中封装UITextView用于渲染内容时,出现文本被截断或超出屏幕的问题:当前代码里的UITextView要么只显示第一行后截断,要么移除content相关设置后内容超出屏幕范围,无法像SwiftUI原生Text组件那样自适应高度完整显示。
复现代码
struct ContentView: View { var body: some View { ScrollView { Text(text) WrappedUITextView(text) }.padding() } } struct WrappedUITextView: UIViewRepresentable { private let textContent: String init(_ textContent: String) { self.textContent = textContent } func makeUIView(context: Context) -> UITextView { let uiTextView = UITextView() uiTextView.backgroundColor = .clear uiTextView.isEditable = false uiTextView.isScrollEnabled = false uiTextView.setContentHuggingPriority(.defaultLow, for: .vertical) uiTextView.setContentHuggingPriority(.defaultLow, for: .horizontal) uiTextView.setContentCompressionResistancePriority(.required, for: .vertical) uiTextView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) return uiTextView } func updateUIView(_ uiTextView: UITextView, context: Context) { uiTextView.text = textContent } } let text = """ Lorem Ipsum is simply dummy text of the printing and typesetting industry. Lorem Ipsum has been the industry's standard dummy text ever since the 1500s, when an unknown printer took a galley of type and scrambled it to make a type specimen book. """
当前渲染效果

解决办法
核心问题是UITextView的自动布局优先级设置错误,导致SwiftUI无法正确识别它的自适应高度需求,调整以下两点即可解决:
修正垂直方向的内容拥抱优先级
将UITextView的垂直内容拥抱优先级设为defaultHigh,告诉SwiftUI优先让视图适应自身内容高度,而非被父视图压缩:uiTextView.setContentHuggingPriority(.defaultHigh, for: .vertical)确保文本更新后重新计算视图尺寸
在updateUIView方法中设置文本后,调用sizeToFit()和layoutIfNeeded(),让UITextView重新计算自身的固有尺寸,确保SwiftUI能获取到正确的高度:func updateUIView(_ uiTextView: UITextView, context: Context) { uiTextView.text = textContent uiTextView.sizeToFit() uiTextView.layoutIfNeeded() }
修改后的完整WrappedUITextView代码
struct WrappedUITextView: UIViewRepresentable { private let textContent: String init(_ textContent: String) { self.textContent = textContent } func makeUIView(context: Context) -> UITextView { let uiTextView = UITextView() uiTextView.backgroundColor = .clear uiTextView.isEditable = false uiTextView.isScrollEnabled = false // 修正垂直方向优先级,确保自适应高度 uiTextView.setContentHuggingPriority(.defaultHigh, for: .vertical) uiTextView.setContentHuggingPriority(.defaultLow, for: .horizontal) uiTextView.setContentCompressionResistancePriority(.required, for: .vertical) uiTextView.setContentCompressionResistancePriority(.defaultLow, for: .horizontal) return uiTextView } func updateUIView(_ uiTextView: UITextView, context: Context) { uiTextView.text = textContent // 强制重新计算尺寸 uiTextView.sizeToFit() uiTextView.layoutIfNeeded() } }
修改后,封装的UITextView就能像SwiftUI原生Text组件一样,自适应内容高度并完整显示全部文本。
内容的提问来源于stack exchange,提问作者Nico
相关产品推荐
相关产品推荐

