我希望UIButton
中有一个UIViewController
在我的SwiftUI应用中的ObservableObject
中运行一个函数。我的需求不止于此,因此我将一些内容整理为以下代码:
UIViewController和代理
protocol TestVCDelegate {
func runTest()
}
class TestVC: UIViewController {
let btnTest = UIButton()
let lblTest = UILabel()
var delegate:TestVCDelegate! = nil
override func viewDidLoad() {
super.viewDidLoad()
view.backgroundColor = UIColor.red
btnTest.translatesAutoresizingMaskIntoConstraints = false
lblTest.translatesAutoresizingMaskIntoConstraints = false
btnTest.backgroundColor = UIColor.green
btnTest.addTarget(self, action: #selector(runTest), for: .touchUpInside)
view.addSubview(btnTest)
btnTest.heightAnchor.constraint(equalToConstant: 100).isActive = true
btnTest.widthAnchor.constraint(equalToConstant: 100).isActive = true
btnTest.topAnchor.constraint(equalTo: view.topAnchor, constant: 100).isActive = true
btnTest.leadingAnchor.constraint(equalTo: view.leadingAnchor, constant: 100).isActive = true
view.addSubview(lblTest)
lblTest.heightAnchor.constraint(equalToConstant: 100).isActive = true
lblTest.widthAnchor.constraint(equalToConstant: 100).isActive = true
lblTest.topAnchor.constraint(equalTo: btnTest.bottomAnchor, constant: 10).isActive = true
lblTest.leadingAnchor.constraint(equalTo: self.view.leadingAnchor, constant: 100).isActive = true
}
@objc func runTest() {
delegate.runTest()
lblTest.text = "hello world!"
}
}
UIViewControllerRepresentable&Coordinator
struct Take2: UIViewControllerRepresentable {
@EnvironmentObject var model: Model
let testVC = TestVC()
func makeUIViewController(context: Context) -> TestVC {
testVC.delegate = context.coordinator
return testVC
}
func updateUIViewController(_ uiViewController: TestVC, context: Context) {
//
}
func makeCoordinator() -> Coordinator {
Coordinator(self)
}
class Coordinator: NSObject, TestVCDelegate {
var parent: Take2
init(_ testViewController: Take2) {
parent = testViewController
}
func runTest() {
print("hello world")
}
}
}
模型
class Model : ObservableObject {
var objectWillChange = PassthroughSubject<Void, Never>()
@Published var lblText = "" {
willSet {
objectWillChange.send()
}
}
func runTest() {
print("yet again, hello world")
lblText = "hello world!"
}
}
每次我尝试在模型中执行runTest()
时,都会出现此错误:
致命错误:在View.body外部读取EnvironmentObject
现在,无论我尝试在Take2
,Coordinator
还是在我的TestVC
中执行此操作,都会发生此错误。我(大多数情况下)理解该错误-如果我应该尝试通过some View
在onAppear
中执行此错误,那么它将起作用。但是-我认为UIViewControllerRepresentable
是View
堆栈中的SwiftUI
(即使不是some View
)。
我成功地将UIKit
属性(获取和设置)公开给SwiftUI堆栈。我也有UIKit
个委托(特别是UIimagepickerController
)委托成功更新了SwiftUI属性。
但是如何从UIKit ObservableObject
在UIButton
中执行功能?