从UIViewController传递变量到SwiftUI视图

5
我找不到一种方法或一个好的教程来解释如何将由UIViewController拥有的变量(String或Int)的值传递给调用视图的SwiftUI视图。
例如:
class ViewController: UIViewController {
    var myString : String = "" // variable of interest
    ....
    
    func methodThatChangeValueOfString(){
        myString = someValue
    }
}

// to make the view callable on SwiftUI
extension ViewController: UIViewControllerRepresentable {
    typealias UIViewControllerType = ViewController
    
    public func makeUIViewController(context: UIViewControllerRepresentableContext<ViewController>) -> ViewController {
        return ViewController()
    }
    
    func updateUIViewController(_ uiViewController: ViewController, context: UIViewControllerRepresentableContext<ViewController>) {
        
    }
    
}

在SwiftUI中,我将拥有

struct ContentView: View {
    var body: some View {
        ViewController()
    }
}

如何在ContentView中使用ViewController中的myString变量?感谢您的提前帮助。

有几种方法,但目标并不是非常清晰。 - Asperi
好的,我来解释一下我的具体问题。在 ViewController 中,我有相机,并使用 Vision 进行对象检测。摄像头检测到的对象名称被保存在变量中,以字符串形式表示。我想使用 SwiftUI 在屏幕上打印字符串,但我无法将数据传递给 SwiftUI 视图。 - Omar El Malak
1个回答

8

使用MVVM模式是SwiftUI推荐的做法。

在SwiftUI View和你的UIKitViewController之间共享一个ViewModel。

我建议你先从基本的苹果SwiftUI教程开始。具体来说,如何“与UIKit接口”。

https://developer.apple.com/tutorials/swiftui/interfacing-with-uikit

import SwiftUI

struct SwiftUIView: View {
    @StateObject var sharedVM: SharedViewModel = SharedViewModel()
    var body: some View {
        VStack{
            UIKitViewController_UI(sharedVM: sharedVM)
            Text(sharedVM.myString)
        }
    }
}

class SharedViewModel: ObservableObject{
    @Published var myString = "init String"
}
//Not an extension
struct UIKitViewController_UI: UIViewControllerRepresentable {
    typealias UIViewControllerType = UIKitViewController
    var sharedVM: SharedViewModel
    
    func makeUIViewController(context: Context) -> UIKitViewController {
        return UIKitViewController(vm: sharedVM)
    }
    
    
    func updateUIViewController(_ uiViewController: UIKitViewController, context: Context) {
        
    }
    
}
class UIKitViewController: UIViewController {
    let sharedVM: SharedViewModel
    
    var runCount = 0
    
    init(vm: SharedViewModel) {
        self.sharedVM = vm
        super.init(nibName: nil, bundle: nil)
        //Sample update mimics the work of a Delegate or IBAction, etc
        Timer.scheduledTimer(withTimeInterval: 1.0, repeats: true) { timer in
            self.runCount += 1
            self.methodThatChangeValueOfString()
            if self.runCount == 10 {
                timer.invalidate()
            }
        }
    }
    
    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func methodThatChangeValueOfString(){
        sharedVM.myString = "method change" + runCount.description
    }
}

struct SwiftUIView_Previews: PreviewProvider {
    static var previews: some View {
        SwiftUIView()
    }
}

有没有办法在View结构体中创建UIKitViewController_UI作为变量,然后传递sharedVM?我需要从视图内部调用UIKitViewController_UI中的一些函数。但是,当我尝试这样做时,它会调用一个“在初始化所有存储属性之前使用'self'”的错误。 - Björn
2
@Björn,你可以创建它,但很可能无法正常工作,因为它将位于 SwiftUI 类中。视图应该保留在结构体中。提出问题,人们可以查看您的最小可重现示例,但听起来您只是设置了变量太早。 - lorem ipsum

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接