将变量从 UIHostingController 传递到 SWIFTUI 视图

Posted

技术标签:

【中文标题】将变量从 UIHostingController 传递到 SWIFTUI 视图【英文标题】:Pass a variable from UIHostingController to SWIFTUI view 【发布时间】:2021-12-19 10:15:15 【问题描述】:

我有一个故事板应用程序,现在从我现有应用程序中的 SwiftUI 视图开始。我有一个填充变量的 API 调用,例如:姓名、姓氏、电子邮件和移动设备。

如何在我的 UIHostingController 中传递 UIKit 变量以在 SwiftUI 视图中显示?

我的故事板 UIKit 文件:

import UIKit
import SwiftUI
class UserDashboardHostVC: UIViewController 
    
    var name = String()
    var surname = String()
    var email = String()
    var mobile = String()
    

    override func viewDidLoad() 
        super.viewDidLoad()
        
        getAPIdata() 
        //this populates the above 4 variables.    
        
        let controller = UIHostingController(rootView: UserDashboard())
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        self.addChild(controller)
        self.view.addSubview(controller.view)
        controller.didMove(toParent: self)
    

我的 SwiftUI 视图:

import SwiftUI

struct UserDashboard: View 
    
    var body: some View 
        NavigationView

           Text(name)
           Spacer()
           Text(surname)
           Spacer()
           Text(email)
           Spacer()
           Text(mobile)
           Spacer()
       
    

【问题讨论】:

您的 UserDashboard 视图文件应该向您显示编译器消息,它无法在范围内找到姓名、姓氏、电子邮件和移动设备。首先在视图中定义这些,但在它的主体之外。 let name: String, let surname: String... 等等。然后,一旦你这样做了,编译器会抛出一个错误,你在 UserDashboardHostVC 中实例化了一个 UserDashboard 的实例,说它没有正确的初始化程序。解决这个问题,你应该被排序。 【参考方案1】:

将这些属性从控制器移动到独立视图模型类中,并将该类的实例传递到 SwiftUI 视图中,如下所示。

*您也可以将相同的模型传递给getAPI 函数来更新模型的属性。 (注意:必须在主队列上更新属性才能刷新 SwiftUI 视图!)

class UserDashboardModel: ObservableObject 
    @Published var name = String()
    @Published var surname = String()
    @Published var email = String()
    @Published var mobile = String()


class UserDashboardHostVC: UIViewController 

    var model = UserDashboardModel()      // << here owner !!


    override func viewDidLoad() 
        super.viewDidLoad()

        getAPIdata()             // << can be injected here
        //this populates the above 4 variables.

        let controller = UIHostingController(rootView: UserDashboard(model: self.model))     // << here !!
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        self.addChild(controller)
        self.view.addSubview(controller.view)
        controller.didMove(toParent: self)
    


struct UserDashboard: View 
    @ObservedObject var model: UserDashboardModel    // << here !!

    var body: some View 
        NavigationView

           Text(model.name)
           Spacer()
           Text(model.surname)
           Spacer()
           Text(model.email)
           Spacer()
           Text(model.mobile)
           Spacer()
       
    

【讨论】:

这行得通,谢谢。只是关于 PreviewProvider 的一个问题,它询问模型并添加了“静态 var 预览:一些视图 UserDashboard(模型:self.model)”但我收到错误“类型'UserDashboard_Previews'没有成员'模型'”。可以解决吗? 您可以在此处查看示例***.com/a/63319045/12299030 或此处***.com/a/66462161/12299030。

以上是关于将变量从 UIHostingController 传递到 SWIFTUI 视图的主要内容,如果未能解决你的问题,请参考以下文章

无法将类型“UIHostingController<AnyView>”的值转换为关闭结果类型“UIHostingController<Page>”

为啥 SwiftUI UIHostingController 有额外的间距?

支持不同 SwiftUI 视图类型的 UIHostingController 数组

尝试使用环境变量从 HostingViewController 呈现 SwiftUI

为啥在 SwiftUI Lifecycle 中将 rootViewController 设置为 UIHostingController 时会出错?

SnapKit snp 无法分配给 UIHostingController