yaa*_*ali 6 uikit ios swift swiftui
我有一个使用Storyboard和UIKit构建的 iOS 项目。现在我想使用SwiftUI开发新屏幕。我向现有Storyboard添加了一个托管视图控制器,并用它来显示我新创建的SwiftUI视图。
但我不知道如何创建一个可以在整个应用程序中的任何地方使用的@EnvironmenetObject 。我应该能够在任何基于 UIKit 的 ViewController 以及SwiftUI视图中访问/设置它。
这可能吗?如果是的话该怎么办呢?在纯SwiftUI应用程序中,我们设置环境对象如下,
@main
struct myApp: App {
@StateObject var item = Item()
var body: some Scene {
WindowGroup {
MainView()
.environmentObject(item)
}
}
}
Run Code Online (Sandbox Code Playgroud)
但就我而言,没有这样的函数,因为它是一个包含AppDelegate和SceneDelegate的现有 iOS 项目。初始视图控制器在 Storyboard 中标记。如何设置它并在应用程序中的任何位置访问该对象?
.environmentObject 修饰符将视图类型从 ItemDetailView 更改为其他类型。强制投射会导致错误。相反,请尝试将其包装到 AnyView 中。
class OrderObservable: ObservableObject {
@Published var order: String = "Hello"
}
struct ItemDetailView: View {
@EnvironmentObject var orderObservable: OrderObservable
var body: some View {
EmptyView()
.onAppear(perform: {
print(orderObservable.order)
})
}
}
class ItemDetailViewHostingController: UIHostingController<AnyView> {
let appDelegate = UIApplication.shared.delegate as! AppDelegate
required init?(coder: NSCoder) {
super.init(coder: coder,rootView: AnyView(ItemDetailView().environmentObject(OrderObservable())))
}
}
Run Code Online (Sandbox Code Playgroud)
这对我有用。这是你所需要的吗?
编辑:好的,所以我通过 ViewController 给出了设置属性。它不像使用属性包装器或视图修饰符那么容易,但它确实有效。我试了一下。请告诉我这是否满足您的要求。另外,我必须摆脱 HostingController 子类。
class ViewController: UIViewController {
var orderObservable = OrderObservable()
override func prepare(for segue: UIStoryboardSegue, sender: Any?) {
guard let myVC = (segue.destination as? MyViewController) else { return }
myVC.orderObservable = orderObservable
}
}
class MyViewController: UIViewController {
var orderObservable: OrderObservable!
var anycancellables = Set<AnyCancellable>()
@IBAction @objc func buttonSegueToHostingVC() {
let detailView = ItemDetailView().environmentObject(orderObservable)
present(UIHostingController(rootView: detailView), animated: true)
orderObservable.$order.sink { newVal in
print(newVal)
}
.store(in: &anycancellables)
}
}
class OrderObservable: ObservableObject {
@Published var order: String = "Hello"
init() {
DispatchQueue.main.asyncAfter(deadline: .now() + 10) {
self.order = "World"
}
}
}
struct ItemDetailView: View {
@EnvironmentObject var orderObservable: OrderObservable
var body: some View {
Text("\(orderObservable.order)")
}
}
Run Code Online (Sandbox Code Playgroud)
基本上,我在 ViewController 类中创建可观察对象,将其传递给 MyViewController 类,最后使用 ItemDetailView 创建一个托管控制器,并设置它的environmentObject 并呈现它。
| 归档时间: |
|
| 查看次数: |
4530 次 |
| 最近记录: |