【问题标题】:Call UIKIT function from SWIFTUI从 SWIFTUI 调用 UIKIT 函数
【发布时间】:2022-01-22 21:20:52
【问题描述】:

我有一个 Storyboard UIKIT 函数 getAcctBalance()。在我的 UIKIT 文件中,我显示了一个 UIHostingController 来加载一个 SWIFTUI 视图。在 SWIFTUI 视图中,我想调用我的函数 getAcctBalance()。

SWIFTUI:

import SwiftUI
import SWXMLHash

struct UserDashboard: View {
    
    @ObservedObject var userModel: UserDashboardModel

    Button(action: {
       UserDashboardHostVC.getAcctBalance() //This function call is not working
    }){
       Text("Load Balance")
    }

    Text(userModel.totalBalance) //by default it is 0.0 and when button is pressed it should return 599
}

UIKIT:

import UIKit

class UserDashboardModel: ObservableObject {
    @Published var totalBalance     = 0.0
}

class UserDashboardHostVC: UIViewController {
    
    var userModel = UserDashboardModel()

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let controller = UIHostingController(rootView: UserDashboard(userModel: self.userModel))
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        self.addChild(controller)
        self.view.addSubview(controller.view)
        controller.didMove(toParent: self)

    }
    func getAcctBalance {
        userModel.totalBalance = 599
}

【问题讨论】:

  • 这似乎有点超出我的想象,我没有看到在这篇文章中使用了 UIHostingController。
  • 这就是为什么我没有将它作为重复发布但它非常相似。在链接中,您从 SwiftUI 开始,然后是 UIViewController,因此您需要 UIViewControllerRepresentable。您从 UIViewController 开始,然后通过主机控制器进入 SwiftUI。但是沟通是一样的。 UserDashboardModel 需要持有对UserDashboardHostVC 的引用,因此Button 可以调用UserDashboardModel 中的方法,然后将调用UserDashboardHostVC 中的方法,就像各种委托一样。

标签: swiftui uikit


【解决方案1】:

这是一个示例

class UserDashboardModel: ObservableObject {
    @Published var totalBalance     = 0.0
    internal var uIViewController: UserDashboardHostVC? = nil
    
    func getAcctBalance(){
        if uIViewController != nil{
            uIViewController!.getAcctBalance()
        }else{
            print("view controller is not connected")
        }
    }
}
struct UserDashboard: View {
    
    @ObservedObject var userModel: UserDashboardModel
    var body: some View{
        VStack{
            Button(action: {
                userModel.getAcctBalance() //Call shared model
            }){
                Text("Load Balance")
            }
            
            Text(userModel.totalBalance.description) //Now it will change
        }.frame(width: 400, height: 400, alignment: .center)
    }
}
class UserDashboardHostVC: UIViewController {
    
    var userModel = UserDashboardModel()
    
    override func viewDidLoad() {
        super.viewDidLoad()
        //Crucial connection
        userModel.uIViewController = self
        let controller = UIHostingController(rootView: UserDashboard(userModel: self.userModel))
        
        self.addChild(controller)
        self.view.addSubview(controller.view)
        controller.view.translatesAutoresizingMaskIntoConstraints = false
        //Update constraints per use case
        controller.view.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
        controller.view.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        controller.didMove(toParent: self)
        
    }
    func getAcctBalance() {
        userModel.totalBalance = 599
    }
}

【讨论】:

  • 我陷入了其他“视图控制器未连接”
  • 如果我拿走 else 并运行 uIViewController!.getAcctBalance() 我得到“致命错误:在展开可选值时意外发现 nil”
  • 看看我在viewDidLoad方法中写了什么。超级调用之后的行。您缺少那行代码。你应该总是在强制之前检查 nil
  • @SebastienDesemberg 你搞定了吗?
  • 抱歉回复晚了。我错过了关键的连接。它运作良好。我喜欢这种方法而不是使用 UIViewControllerRepresentable,我认为它是更智能的代码。谢谢。
猜你喜欢
  • 1970-01-01
  • 2021-09-25
  • 1970-01-01
  • 1970-01-01
  • 2021-05-18
  • 2021-10-09
  • 2020-12-19
  • 2020-10-06
  • 2020-04-01
相关资源
最近更新 更多