使用 Text 加载长文本的卡顿问题
了解如何避免在使用 Text 组件时,因为加载长文本导致的卡顿问题。

问题背景
在一个 ScrollView(.horizontal)
滑动组件中,使用 LazyHStack
+ ForEach
加载视图。
当横向滑动页面时,能感受到轻微但明显的掉帧。当使用 .scrollTargetBehavior()
添加滑动对齐行为后,卡顿会更加明显。

原因分析
通过控制变量实验,发现是因为在 BookmarkDetailView()
组件中,使用 Text 组件加载了一个长文本:
Text(bookmark.bookDetails.intro)
某些对象 bookmark.bookDetails.intro 的值可能较长,超过 1000 个字,此时就会感觉到明显的滑动卡顿掉帧。
通过懒加载显示长文本
创建一个 lazyText
组件,通过该组件显示长文本。
- 默认显示 8 行文字
- 用户可以点击更多,在一个 sheet 窗口中显示完整内容。
import SwiftUI
struct LazyText: View {
let text: String
let title: String
@State private var isShowingFullText = false
let maxChars: Int
init(_ text: String, title: String = "简介", maxChars: Int = 200) {
self.text = text
self.title = title
self.maxChars = maxChars
}
var body: some View {
VStack(alignment: .leading, spacing: 8) {
if text.count > maxChars {
Text(text.prefix(maxChars) + "...")
.overlay(
Text("更多")
.foregroundColor(.blue)
.padding(.leading, 4)
.background(Color(UIColor.systemBackground))
.alignmentGuide(.trailing) { d in d[.trailing] }
.frame(maxWidth: .infinity, alignment: .trailing),
alignment: .bottomTrailing
)
.contentShape(Rectangle())
.onTapGesture {
isShowingFullText = true
}
} else {
Text(text)
}
}
.sheet(isPresented: $isShowingFullText) {
NavigationStack {
ScrollView {
Text(text)
.padding()
}
.navigationTitle(title)
.navigationBarTitleDisplayMode(.inline)
.toolbar {
ToolbarItem(placement: .topBarTrailing) {
Button("完成") {
isShowingFullText = false
}
}
}
}
}
}
}