Ускорьте редактирование длинного текста

#text #swiftui

#текст #свифтуи

Вопрос:

В следующем коде производительность резко снижается, поскольку текст становится длиннее из-за того, что представление перерисовывается для каждого введенного символа (из-за textViewDidChange). Существует также ряд неприятных побочных эффектов, таких как вставка перерывов в предложениях, вероятно, из-за автозамены или какого-либо другого механизма. Если я закомментирую или исключу функцию textViewDidChange, производительность значительно улучшится, а побочные эффекты исчезнут, но тогда я больше не смогу захватить текст, чтобы сохранить его или опросить его на лету.

Кто-нибудь знает, как это обойти? Я подумал, что если бы я мог просто не обновлять текстовую переменную до тех пор, пока фокус не переместится в другое представление, то я мог бы захватить текст до того, как его нужно будет сохранить. Если это может сработать, я не могу определить, как уловить изменение фокуса. Я пытался реализовать textViewDidEndEditing, но это срабатывает только тогда, когда родительское представление завершает редактирование. Я использую кнопку «Сохранить» и хочу затем записать текст.

Я понимаю, что есть доступное представление редактора текста, но оно так же медленно работает с большим текстом, поэтому я предполагаю, что оно делает то же самое.

 import SwiftUI  struct TextView: UIViewRepresentable {    @Binding var text: String  @Binding var textStyle: UIFont.TextStyle    func makeUIView(context: Context) -gt; UITextView {  let textView = UITextView()    textView.delegate = context.coordinator  textView.font = UIFont.preferredFont(forTextStyle: textStyle)  textView.autocapitalizationType = .none  textView.isSelectable = true  textView.isUserInteractionEnabled = true    return textView  }    func updateUIView(_ uiView: UITextView, context: Context) {  uiView.text = text  uiView.font = UIFont.preferredFont(forTextStyle: textStyle)  }    func makeCoordinator() -gt; Coordinator {  Coordinator($text)  }    class Coordinator: NSObject, UITextViewDelegate {  var text: Bindinglt;Stringgt;   init(_ text: Bindinglt;Stringgt;) {  self.text = text  }    func textViewDidChange(_ textView: UITextView) {  self.text.wrappedValue = textView.text  }  } }   

Просмотр содержимого

 import SwiftUI  struct ContentView: View {    @State private var message = ""  @State private var textStyle = UIFont.TextStyle.body    var body: some View {  ZStack(alignment: .topTrailing) {  TextView(text: $message, textStyle: $textStyle)  .padding(.horizontal)    Button(action: {  self.textStyle = (self.textStyle == .body) ? .title1 : .body  }) {  Image(systemName: "textformat")  .imageScale(.large)  .frame(width: 40, height: 40)  .foregroundColor(.white)  .background(Color.purple)  .clipShape(Circle())    }  .padding()   }  } }  struct ContentView_Previews: PreviewProvider {  static var previews: some View {  ContentView()  } }   

Комментарии:

1. Закомментируйте строки в update функции, которая, вероятно, создает какой-то странный цикл. Установите там текст только в том случае, если он еще не совпадает. Также передайте родительскую привязку против привязки к координатору Привязка плохо работает в классе

2. Я не испытываю никаких проблем с производительностью при использовании вашего кода.