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

SwiftUI超长文本显示空白问题求助

10万字长文本在SwiftUI Text组件显示空白的解决办法

问题现象

  • 约10万字的长文本,用TextField可正常显示但存在其他问题,不愿使用该组件
  • 使用Text组件时仅显示空白,但会占据对应布局位置,外层ScrollView可正常滚动
  • 尝试添加.lineLimit(nil)、.fixedSize(horizontal: false, vertical: true)属性后无改善
  • 改用读取Markdown文件的方式加载文本,结果仍为空白

解决思路与方案

SwiftUI的Text组件在处理超大量文本时,会因一次性渲染压力过大出现内容空白(布局空间已预留但渲染未完成)。以下是三种可行的解决方法:

方法1:分段懒加载文本

将长文本分割为小段落,通过LazyVStack逐个渲染,利用懒加载降低单次渲染压力:

VStack(alignment: .leading, spacing: 3) {
    ScrollView {
        LazyVStack(spacing: 8) {
            if let cnt = current?.content {
                // 按换行符分割段落,可根据文本格式调整分割规则
                let paragraphs = cnt.components(separatedBy: "\n")
                ForEach(paragraphs, id: \.self) { paragraph in
                    Text(paragraph)
                        .frame(maxWidth: .infinity, alignment: .leading)
                }
            }
        }
    }
}

方法2:封装UIKit的UITextView

UIKit的UITextView对长文本的处理性能更稳定,可封装为SwiftUI组件使用:

import SwiftUI
import UIKit

struct LargeTextView: UIViewRepresentable {
    let text: String
    
    func makeUIView(context: Context) -> UITextView {
        let textView = UITextView()
        textView.isEditable = false
        textView.isScrollEnabled = false // 依赖外层SwiftUI的ScrollView,禁用内部滚动
        textView.text = text
        textView.font = UIFont.systemFont(ofSize: 16)
        return textView
    }
    
    func updateUIView(_ uiView: UITextView, context: Context) {
        uiView.text = text
    }
}

// 使用示例
VStack(alignment: .leading, spacing: 3) {
    ScrollView {
        if let cnt = current?.content {
            LargeTextView(text: cnt)
        }
    }
}

方法3:分段解析Markdown文本

若坚持使用Markdown加载,避免一次性解析全部内容,分段解析后逐个渲染:

struct markdownFileView: View {
    let filepath = Bundle.main.url(forResource: "test", withExtension: "md")
    
    var body: some View {
        ScrollView {
            LazyVStack(spacing: 8) {
                if let url = filepath, let content = try? String(contentsOf: url) {
                    let paragraphs = content.components(separatedBy: "\n")
                    ForEach(paragraphs, id: \.self) { paragraph in
                        if let attrStr = try? AttributedString(
                            markdown: paragraph,
                            options: AttributedString.MarkdownParsingOptions(
                                interpretedSyntax: .inlineOnlyPreservingWhitespace
                            )
                        ) {
                            Text(attrStr)
                                .frame(maxWidth: .infinity, alignment: .leading)
                        }
                    }
                }
            }
        }
    }
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 20:40:15