我有一个 SwiftUI 项目,它使用
EnvironmentObject
相应地更新标签。在同一个项目中,我有一个 UIViewController
,通过使视图控制器符合 UIViewControllerRepresentable
协议,我将其托管在 SwiftUI 视图中。我希望能够通过 UIKit 代码控制 SwiftUI 视图中的标签。有没有办法可以从 UIKit 代码中传递 EnvironmentObject?如果没有,将数据从基于 UIKit 的视图传递到 SwiftUI 视图的理想方法是什么。
请注意,为了在这里发布问题,我简化了项目。这是代码:
MyApp.swift
import SwiftUI
@MainActor class Options: ObservableObject {
@Published var option = 1
}
@main
struct MyApp: App {
@StateObject var options = Options()
var body: some Scene {
WindowGroup {
ContentView().environmentObject(options)
}
}
}
ContentView.swift
import SwiftUI
struct ContentView: View {
@EnvironmentObject var options: Options
var body: some View {
VStack {
Image(systemName: "globe")
.imageScale(.large)
.foregroundStyle(.tint)
if options.option == 0 {
Text("Hello, world!")
} else {
Text("Other Options")
}
MyUIView()
}
.padding()
}
}
#Preview {
ContentView().environmentObject(Options())
}
MyUIViewController.swift
import UIKit
class MyUIViewController: UIViewController {
var btn: UIButton!
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
var config = UIButton.Configuration.filled()
config.title = "Change Option"
btn = UIButton(configuration: config)
btn.addAction(UIAction(handler: { UIAction in
/* Here, I need to change the option
and pass it to update the label in my SwiftUI view. */
}), for: .touchUpInside);
btn.frame = CGRect(x: 0, y: 0, width: 100, height: 50)
self.view.addSubview(btn)
}
}
MyUIView.swift
import SwiftUI
struct MyUIView: UIViewControllerRepresentable {
func makeUIViewController(context: Context) -> UIViewController {
return MyUIViewController()
}
func updateUIViewController(_ uiViewController: UIViewController, context: Context) {
}
}
只需添加
let options: Options
到 MyUIViewController 和 MyUIView 然后添加一个 init 到 MyUIViewController
init(options: Options){
self.options = options
super.init()
}
Xcode 将显示一些错误,这些错误会稍微修改您的代码,但修复这些错误应该很简单。