如何让UIButton(UIViewControllerRepresentable)在模型中触发动作?

时间:2019-08-27 13:54:51

标签: swiftui

我希望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

现在,无论我尝试在Take2Coordinator还是在我的TestVC中执行此操作,都会发生此错误。我(大多数情况下)理解该错误-如果我应该尝试通过some ViewonAppear中执行此错误,那么它将起作用。但是-我认为UIViewControllerRepresentable View堆栈中的SwiftUI(即使不是some View)。

我成功地将UIKit属性(获取和设置)公开给SwiftUI堆栈。我也有UIKit个委托(特别是UIimagepickerController)委托成功更新了SwiftUI属性。

但是如何从UIKit ObservableObjectUIButton中执行功能?

0 个答案:

没有答案