SwiftUI TextEditor 绑定到 $[Note].content — 性能缓慢?

问题描述 投票:0回答:1

我正在构建简单的文本编辑器,它可以处理多个打开的文件。我有 NotesManager,它存储所有打开的文档,并且我使用

NavigationLink
将每个注释的绑定传递给视图。

由于某种原因,即使在小文件(如 20 行)上,文本字段更新也非常慢 快速插入

  1. 它应该工作得这么慢还是我错过了一些标记//惰性更新方法?
  2. 如果是 SwiftUI 限制,我是否应该使用不带反应式绑定的 AppKit 来实现所需的性能?

这里是慢重画的demo:

enter image description here

NotesManager.swift

class NotesManager: ObservableObject {
    @Published var notes: [Note] = []
    
    var fileMonitors: [UUID: DispatchSourceFileSystemObject] = [:]

    func add(note: Note) {
        notes.append(note)
        monitorFile(for: note)
    }

    private func monitorFile(for note: Note) {
        ...
    }

    private func loadFileContent(for note: Note) {
        ...
        add(note)
    }
    
    ...
}

ContentView.swift

struct ContentView: View {
    @State private var selectedNoteID: UUID?
    @EnvironmentObject var notesManager: NotesManager
    
    var body: some View {
        NavigationSplitView {
            List($notesManager.notes, selection: $selectedNoteID) { $note in
                NavigationLink(destination: {
                    TextEditorView(note: $note)
                        .frame(minWidth: 400, maxWidth: .infinity, minHeight: 400, maxHeight: .infinity)
                }) {
                    SidebarItemView(note: note, selectedNoteID: $selectedNoteID)
                        .tag(note.id)
                }
            }
        } detail: {
            Text("Open document to get started")
        }
    }
}

TextEditorView.swift

// Using CodeEditorView package

struct TextEditorView: View {
    @Binding var note: Note
    @State var text: String = ""
    @State var searchQuery: String = ""
    @State private var messages: Set<TextLocated<Message>> = Set ()
    @State private var editPosition: CodeEditor.Position = CodeEditor.Position()
    
    var body: some View {
        VStack {
            CodeEditor(text: $note.content, position: $editPosition, messages: $messages, language: .swift())
                .tag(note.id)
//                  .environment(\.codeEditorTheme, colorScheme == .dark ? Theme.defaultDark : Theme.defaultLight)
        }
        
    }
}
swift swiftui appkit
1个回答
0
投票

文本编辑器直接修改 NotesManager 中的 Notes 数组,这会在整个层次结构(包括 NavigationSplitView)中传播视图更新。

我们可以通过将 TextEditorView 的注释绑定与 NotesManager 的已发布注释数组分离来提高性能。

我看到两种方法:

  1. 将注释的内容与 NotesManager 的已发布属性分开(例如,具有已发布的注释 ID 数组和未发布的注释存储)
  2. 将要更新的单个注释从列表中分离出来(例如,创建一个副本作为 TextEditorView 的 State,并在特定时间间隔或事件(例如,打字停止时)有目的地更新列表)。
© www.soinside.com 2019 - 2024. All rights reserved.