#swiftui
Вопрос:
Как передавать данные между UIViewController
и struct ContentView
?
Я пробовал, ObservableObject
но не могу обновить данные.
Комментарии:
1. Не могли бы вы подробнее рассказать о том, что вы пытаетесь сделать? Публикация исходного кода (того, что вы уже пробовали), безусловно, поможет.
2. Вы на это смотрели
updateUIViewController(_:,context:)
?3. в моем приложении(UIKit) есть представление, содержащее контейнер(Swiftui), и я хочу передать данные из моего представления(UIViewController) в мой контейнер(UIHostingController).
4. Вы можете прикрепить
environmentObject
к своему корневому представлению SwiftUI. Я напишу ответ, объясняющий, как его использовать.
Ответ №1:
Чтобы передать данные из a UIViewController
в структуру SwiftUI внутри an UIHostingController
, вы можете присоединить environmentObject
ее к SwiftUI rootView
:
let vc = UIHostingController(rootView: YourContentView().environmentObject(yourEnvironmentObject))
Конечно, вам нужно будет создать объект ObservableObject и добавить его в свою SwiftUI-структуру.
Создайте объект ObservableОбъект:
class TypeOfEnvironmentObject: ObservableObject {
@Published var data = "myData"
}
Добавьте его в свою структуру:
@EnvironmentObject var yourEnvironmentObject: TypeOfEnvironmentObject
Комментарии:
1. Спасибо! Ребята.. Да, я уже делал это раньше. Но когда значение данных обновляется, моя структура не принимает обновления, она остается со значением инициализации.
2. Хорошо, я думаю, я понял, что вы пытаетесь сделать. Если я вас правильно понял, объединенная структура-это то, что вы ищете: developer.apple.com/documentation/combine/…
3. С помощью Combine вы можете подключить издателя в вашем UIViewController к подписчику в вашей SwiftUI-структуре. Когда ваши данные изменятся, вы можете использовать издателя, чтобы уведомить подписчика.
4. Я пытаюсь, но я не понимаю концепции. Не могли бы вы привести мне небольшой пример?😅
5. большое вам спасибо, ребята, за ваши ответы. Я добился успеха
ObservableObject
и постараюсь подробно рассказать, может ли это помочь кому-то еще.
Ответ №2:
Я нашел существующие ответы запутанными/неполными, возможно, что-то изменилось вокруг общего вывода в Swift 5.3 и т. Д. Хотя вы можете добавить объект среды в представление UIHostingController, это, по-видимому, противоречит типам (т. Е. Общий параметр UIHostingController нуждается в конкретном типе). Добавление AnyView
разрешает это:
import UIKit
import SwiftUI
struct TutorialView: View {
@EnvironmentObject private var integration: TutorialIntegrationService
var body: some View {
Text("Hi").navigationBarTitle("test: (integration.id)")
}
}
class TutorialIntegrationService: ObservableObject {
@Published var id: Int = 0
}
class TutorialViewController: UIHostingController<AnyView> {
let integration = TutorialIntegrationService()
required init?(coder: NSCoder) {
super.init(coder: coder,rootView: AnyView(TutorialView().environmentObject(integration)));
}
}
Ответ №3:
class myclassname: ObservableObject
- в классе создайте переменную с
@Published var myvar
помощью и создайтеinit(myvar: type) {
self.myvar = myvar
} - в моем
UIViewController
творенииprivate var model = myclassname(myvar: XXX)
и вviewWillAppear------>let vc = myclassname(myvar: myvar)
let childView = UIHostingController(rootView: ContentView(model: vc))- в моем
struct ---> @ObservedObject var model: myclassname
- в моем
Комментарии:
1. Это работает. Следует отметить, что если ваше представление принимает свойство $привязки (например, в предварительном просмотре вы используете @State), то $model.property будет работать вместо него, если вы выполните действия, описанные здесь.