如何在SwiftUI中高效展示大体积文本并支持AttributedString样式?
如何在SwiftUI中高效展示带样式的只读大体积文本
问题场景回顾
当使用ScrollView嵌套Text加载大体积文本时,会出现CPU占用率100%、应用卡死的情况:
struct ContentView: View { @Binding var document: TextInScrollviewPerformanceDocument var body: some View { ScrollView { Text(document.text) } } }
单独使用Text不会卡顿,但文本会被截断且无法滚动;使用TextEditor则能高效处理大文本,但需要调整为只读状态并支持富文本样式。
可行解决方案
方案1:改造TextEditor为只读富文本容器
TextEditor原生支持AttributedString且具备大文本优化,只需禁用编辑功能并调整样式,即可作为高效的只读富文本展示组件:
struct ReadOnlyLargeAttributedView: View { let attributedText: AttributedString var body: some View { TextEditor(text: .constant(attributedText)) .disabled(true) // 完全禁用编辑,变为只读 .scrollContentBackground(.hidden) // 移除默认背景(可选) .background(Color.clear) // 适配SwiftUI页面背景(可选) .foregroundColor(.primary) // 保持文本默认色调(可选) } }
优势:无需跨层封装,直接复用SwiftUI组件,同时支持AttributedString的所有样式设置(字体、颜色、段落间距等)。
方案2:封装UIKit的UITextView(更精细控制)
如果需要更灵活的样式或交互控制,可封装UIKit的UITextView——它天生支持大文本按需渲染,设置为只读后性能优异,且支持完整的NSAttributedString样式:
struct ReadOnlyAttributedTextView: UIViewRepresentable { let attributedText: NSAttributedString func makeUIView(context: Context) -> UITextView { let textView = UITextView() textView.isEditable = false textView.isScrollEnabled = true textView.backgroundColor = .clear textView.textContainerInset = UIEdgeInsets(top: 8, left: 8, bottom: 8, right: 8) // 自定义内边距 return textView } func updateUIView(_ uiView: UITextView, context: Context) { uiView.attributedText = attributedText } } // 使用示例 struct ContentView: View { let largeAttributedContent: NSAttributedString var body: some View { ReadOnlyAttributedTextView(attributedText: largeAttributedContent) } }
优势:完全继承UITextView的大文本优化机制,可自定义滚动行为、文本容器属性等,适合复杂样式需求。
卡顿原因说明
SwiftUI的Text嵌套ScrollView时,会一次性渲染全部文本内容,大文本场景下计算量直接拉满CPU;而TextEditor(底层基于UITextView)采用按需渲染策略,仅渲染可视区域及附近的文本块,大幅降低了资源占用。
内容的提问来源于stack exchange,提问作者conorgriffin
相关产品推荐
相关产品推荐

