在主详细信息应用程序中,我有一个项目列表,以及每个项目的详细信息视图。在详细信息视图中,有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)
}
}
}
我尝试在updateUIView
中设置UITextViewDelegate,但存在相同的问题。我们如何强制SwiftUI更新此自定义TextView,以便为每个协调器设置UITextViewDelegate
?
P / S 1:如果我使用普通的TextField,那么它将起作用。它会更新所选书籍的文字
P / S 2:如果我直接通过$store.selectedBook.name
而不是使用下标$store.books[store.selectedIndex].name
,那么它也可以工作