#ios #swift #swiftui #uiviewrepresentable #environmentobject
Вопрос:
У меня есть простой класс для хранения некоторых данных в моем приложении SwiftUI:
final class UserData: ObservableObject {
@Published var id = 1
@Published var name = "Name"
@Published var description = "Initial text"
}
Я также определил его как EnvironmentObject
в основной структуре приложения:
ContentView(document: file.$document)
.environmentObject(UserData())
В моем представлении содержимого я встроил текстовое представление UIKit:
EditorTextView(document: $document.text)
Где EditorTextView UITextView
-это то, что применяется через UIViewRepresentable
.
Теперь я пытаюсь обновить данные пользователя в EditorTextView, например, сохранить некоторые пользовательские данные UserData.description
. Поэтому я определил класс внутри своего координатора следующим образом (код просто для примера):
class Coordinator: NSObject, UITextViewDelegate {
@ObservedObject var userData = UserData()
...
// Somewhere in the code, I update UserData when user taps Enter:
func textViewDidChange(_ textView: UITextView) {
if (textView.text.last == "n") {
userData.description = "My New Text"
}
}
Моя проблема в том, что:
Хотя он обновляется с помощью «Мой новый текст» (как показывает отладчик), значение userData.description
снова инициируется со значением «Начальный текст». Это похоже на то, как если бы класс UserData создавался каждый раз.
Я пытался использовать @StateObject вместо @ObservedObject, но это не имеет значения.
Комментарии:
1. Вы должны решить, является ли это объектом окружающей среды или наблюдаемым объектом?
2. Это объект среды (чтобы сделать его доступным для всех представлений), но я использовал
@ObservedObject
его в оболочке uikit, потому что я не мог@EnvironmentObject
там использовать
Ответ №1:
«Это похоже на то, как если бы класс UserData создавался каждый раз».
Он создается каждый раз, прямо здесь:
class Coordinator: NSObject, UITextViewDelegate {
@ObservedObject var userData = UserData() // <--- here
Попробуйте вместо этого и передайте данные пользователя извне:
class Coordinator: NSObject, UITextViewDelegate {
@ObservedObject var userData: UserData
Как правило, вы также делаете это в своей основной структуре приложения:
@StateObject var userData = UserData()
...
ContentView(document: file.$document).environmentObject(userData)
Комментарии:
1.Спасибо, но как инициализировать данные пользователя в функции инициализации координатора?
init(_ parent: EditorTextView) {
self.parent = parent
}
2. У вас есть «@ObservedObject var userData: данные пользователя» в родительском файле. Затем в координаторе у вас есть инициализация с родителем, затем вы можете ссылаться на нее в координаторе, например: «self.parent.userData».
3. Поэтому я перешел
@ObservedObject var userData: UserData
от координатора к родителю, который является EditorTextView, но начинают появляться ошибки. Я создал Минимальный воспроизводимый пример, пожалуйста, посмотрите здесь4. Я не могу загрузить ваш код с этого сайта. Из моего краткого взгляда на это: мне ясно, что вам нужно прочитать о ObservedObject и EnvironmentObject, как их использовать и передавать из одного представления в другое. Простое руководство по использованию находится по адресу: hackingwithswift.com/quick-start/swiftui/… В вашем представлении контента у вас даже нет: «@EnvironmentObject var userData: Данные пользователя». Мой совет: изучите немного больше о ObservedObject и EnvironmentObject.