Swiftui 如何让UIButton(UIViewControllerRepresentable)触发模型中的操作?
我想让Swiftui 如何让UIButton(UIViewControllerRepresentable)触发模型中的操作?,swiftui,Swiftui,我想让ui视图控制器中的ui按钮在我的SwiftUI应用程序中的observeObject中运行函数。我的需求比这更大,所以我在代码中删减了一些内容: UIViewController和委托 protocol TestVCDelegate { func runTest() } class TestVC: UIViewController { let btnTest = UIButton() let lblTest = UILabel() var delegate:
ui视图控制器中的ui按钮
在我的SwiftUI应用程序中的observeObject
中运行函数。我的需求比这更大,所以我在代码中删减了一些内容:
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!"
}
}
类模型:ObservableObject{
var objectWillChange=PassthroughSubject()
@已发布的变量lblText=“”{
意志{
objectWillChange.send()
}
}
func runTest(){
打印(“再一次,你好,世界”)
lblText=“你好,世界!”
}
}
每次我尝试在我的模型中执行runTest()
,都会出现以下错误:
致命错误:读取EnvironmentObject outside View.body
现在,无论我是在Take2
中,还是在协调器中,还是在我的TestVC
中,都会发生此错误。我(大部分)理解错误-如果我尝试通过onAppear
在some视图中执行此操作,它会工作。但是-我认为UIViewControllerRepresentable
是SwiftUI
堆栈的视图(即使它不是某些视图
)
我已经成功地将UIKit
属性(get和set)公开到SwiftUI堆栈中。我还有UIKit
代理(特别是UIimagepickerController
)成功更新SwiftUI属性
但是如何从UIKitUIButton
执行ObservableObject
中的函数呢?可能有背景说明为什么需要查看.body
。您是否尝试过间接寻址-包装器视图
拥有环境对象并将其传递到Take2
aPassthroughSubject
?您可以将此发布服务器与.onReceive(publisher)
一起在包装器中使用,并调用@EnvironmentObject
上的方法,而Take2
只发送到此发布服务器上的信号以发出函数调用。我知道这是一个解决办法,但任何其他方法可能都更复杂。或者您可以使用@已发布的setter,因为setter变量是允许的可以调用更多的willSet/didSet。或者他们可以?相互测试。我一定会调查的。谢谢结果我很可能把我的问题弄错了。我(还)没有能够使用@Fabian的建议创建一个包装器视图
——但到目前为止,我有了更好的方法-通知
。(Doh!)我想看看我是否能够成功地应用来自合并
(因此,mistag)的发布者-订阅者模式,我将在一天内为其他人在这里发布我的答案。可能需要查看.body
的背景原因。您是否尝试过间接寻址-包装器视图
拥有环境对象并将其传递到Take2
aPassthroughSubject
?您可以将此发布服务器与.onReceive(publisher)
一起在包装器中使用,并调用@EnvironmentObject
上的方法,而Take2
只发送到此发布服务器上的信号以发出函数调用。我知道这是一个解决办法,但任何其他方法可能都更复杂。或者您可以使用@已发布的setter,因为setter变量是允许的可以调用更多的willSet/didSet。或者他们可以?相互测试。我一定会调查的。谢谢结果我很可能把我的问题弄错了。我(还)没有能够使用@Fabian的建议创建一个包装器视图
——但到目前为止,我有了更好的方法-通知
。(Doh!)我想看看我是否能成功地应用来自Combine
(因此,mistag)的发布者-订阅者模式,我将在一天内为其他人在这里发布我的答案。