英文:
Bad SwiftUI performance when scrolling a text view with ~1000 lines
问题
我创建了一个简单的 SwiftUI macOS 应用程序,允许用户导入文本文件,然后显示文本。当导入一个相当大的文本文件(1500行)时,在使用滚动条滚动后,视图会停顿几秒钟。使用分析器,我可以看到 CPU 使用率非常高,出现严重的停顿。有关可能导致这种情况的代码问题的想法吗?谢谢。
英文:
I've created a simple SwiftUI macOS app that allows users to import a text file and then displays the text. When importing a decently sized text file (1500 lines) the view will hang for several seconds after scrolling using the scrollbar. Using the profiler I can see the CPU usage is very high and has Severe Hangs. Any ideas the issue with my code that might be causing this? Thank you.
struct ContentView: View {
private var loggingView = LoggingView()
var body: some View {
loggingView
}
}
struct LoggingView: View {
@StateObject private var model = LoggingModel()
var body: some View {
ScrollView {
if model.data.isEmpty {
Text("Add a file to begin.")
} else {
Text(model.data).frame(maxWidth: .infinity)
}
}
.toolbar {
ToolbarItem(placement: .principal) {
Button(action: model.addFilePath) {
Text("New File")
Label("Import", systemImage: "square.and.arrow.down")
}
}
}
}
}
class LoggingModel: ObservableObject {
@Published var data: String = ""
func addFilePath() {
let dialog = NSOpenPanel()
dialog.title = "Choose a .txt file";
dialog.allowedContentTypes = [.text]
if (dialog.runModal() == NSApplication.ModalResponse.OK) {
let result = dialog.url // Pathname of the file
guard let result else {
return
}
load(file: result.path)
}
}
func load(file: String) {
do {
let contents = try String(contentsOfFile: file)
DispatchQueue.main.async {
self.data = contents
}
} catch let error as NSError {
print(error.localizedDescription)
}
}
}
答案1
得分: 2
你应该在ScrollView
中使用LazyVStack
,并修改你的代码如下以实现所需效果:
ScrollView {
LazyVStack {
// 这里放你的视图
}
}
通过在ScrollView
中使用LazyVStack
:
- 你可以创建一个垂直增长的堆栈,仅在需要时生成项目。
- 这种方法通过仅渲染屏幕上可见的项目来提高性能,特别是在处理大型数据集时。
如果你想要一个水平排列的堆栈,可以使用LazyHStack
。
类似地,还有LazyHGrid
可用于类似网格的布局。
英文:
You should use LazyVStack
in the ScrollView
and modifier your code as follows to achieve the desired effect:
ScrollView {
LazyVStack {
// Your views here
}
}
By using LazyVStack
within the ScrollView
:
- You can create a vertically growing stack that generates items only as needed.
- This approach improves performance by rendering only the visible items on the screen, especially when dealing with large data sets.
If you want a horizontally arranged stack, you can use LazyHStack
instead.
Similarly, there is LazyHGrid
available for grid-like layouts.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论