В приложении основных деталей у меня есть список элементов и подробный вид для каждого элемента. В подробном представлении есть 1 пользовательский ввод текста, поэтому я использую UIViewRepresentable
struct TextView: UIViewRepresentable {
@Binding var text: String
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
func makeUIView(context: Context) -> UITextView {
let myTextView = UITextView()
myTextView.delegate = context.coordinator
return myTextView
}
func updateUIView(_ uiView: UITextView, context: Context) {
uiView.text = text
}
class Coordinator : NSObject, UITextViewDelegate {
var parent: TextView
init(_ uiTextView: TextView) {
self.parent = uiTextView
}
func textViewDidChange(_ textView: UITextView) {
self.parent.text = textView.text
}
}
}
Когда пользователь выбирает элемент из списка, мы показываем подробный вид для этого элемента. Все отлично работает при отображении данных. Однако после установки точек останова я вижу, что пользовательский TextView
создается ровно 1 раз, поэтому myTextView.delegate = context.coordinator
устанавливается только для первого элемента
Так что, когда пользователь выбирает другой элемент и редактирует ввод текста в в подробном представлении всегда обновляется первый элемент в списке.
Вот как используется TextView
struct Book {
var name: String = ""
}
class Store: ObservableObject {
@Published var books: [Book] = []
}
struct MainView: View {
@EnvironmentObject var store: Store
var body: some View {
List {
ForEach(store.books.enumerated().map({ $0 }), id: \.element.id) { index, book in {
Text(book.name)
.onTapGesture {
self.store.selectedIndex = index
}
}
}
HStack {
TextView($store.books[store.selectedIndex].name)
}
}
}
Я попытался установить UITextViewDelegate в updateUIView
, но та же проблема. Как мы можем заставить SwiftUI обновить этот пользовательский TextView так, чтобы UITextViewDelegate
был установлен для каждого координатора?
P / S 1: Если я использую обычный TextField, тогда он работает. Обновляется текст для выбранной книги
P / S 2: Если я передам напрямую $store.selectedBook.name
вместо использования нижнего индекса $store.books[store.selectedIndex].name
, то он тоже будет работать