如何在主局部视图中重新加载UIViewRepresentable

时间:2020-02-14 06:47:31

标签: ios swift textview swiftui uiviewrepresentable

在主详细信息应用程序中,我有一个项目列表,以及每个项目的详细信息视图。在详细信息视图中,有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,那么它也可以工作

0 个答案:

没有答案