如何从 SwiftUI 视图导航到 UIKit UIViewController

问题描述 投票:0回答:6

到目前为止,我有一个完全使用 UIKit 构建的应用程序。但是,我希望能够开始实现一些 SwiftUI 视图来替换一些 UIViewController。

我已经能够通过点击按钮从 UIViewController 导航到 SwiftUI View:

    @IBAction func buttonTapped(_ sender: Any) {
        let newView = UIHostingController(rootView: SwiftUIView(viewObj: self.view, sb: self.storyboard, dismiss: self.dismiss) )
        view.window?.rootViewController = newView
        view.window?.makeKeyAndVisible()
    }

我的问题是,如何从单个 SwiftUI View 转换到 UIViewController?(因为应用程序的其余部分位于 UIKit 中)?我在 SwiftUI 视图中有一个按钮,点击即可导航回 UIViewController。我试过了:

  1. view
    storyboard
    对象传递给 SwiftUI View,然后调用执行类似于上面代码的操作来更改当前视图控制器。然而,当在模拟器上尝试时,没有任何反应。
  2. 使用
    .present
    以模态方式显示 SwiftUI 视图。这有效,我可以允许 SwiftUI 视图
    .dismiss
    本身。但是,这仅在模式下有效,我希望使其正常工作(即更改屏幕)

这是我简单的 SwiftUI 视图:

struct SwiftUIView: View {
    var viewObj:UIView? // Perhaps use this for transition back?
    var sb:UIStoryboard?
    var dismiss: (() -> Void)?

    var body: some View {

        Button(action: {
            // Do something here to Transition
        }) {
            Text("This is a SwiftUI view.")
        }
    }
}

我无法理解如何将 SwiftUI 正确集成到 UIKit 中,而不是相反,我不确定 UIViewControllerRepresentable 是否是这个问题的答案。任何对此问题的解决方案、替代方案或有用的知识都非常感激。再次感谢!

    

swift uiviewcontroller uikit swiftui swiftui-navigationlink
6个回答
11
投票

我尝试通过使用闭包回调来遵循你的方法。

struct SwiftUIView: View { var dismiss: (() -> Void)? var present: (()->Void)? var body: some View { VStack(spacing: 20) { Button(action: { self.dismiss?() }) { Text("Dismiss me") } Button(action: { self.present?() }) { Text("Present some UIViewController") } } } }

当您呈现 UIHostingController 时,您想要实现 2 个闭包回调:

@IBAction func buttonTapped(_ sender: Any) { let hostingController = UIHostingController(rootView: SwiftUIView()) hostingController.rootView.dismiss = { hostingController.dismiss(animated: true, completion: nil) } hostingController.rootView.present = { let destination = UIStoryboard(name: "Main", bundle: nil).instantiateViewController(identifier: "VC_TO_PRESENT") hostingController.present(destination, animated: true, completion: nil) } present(hostingController, animated: true, completion: nil) }



4
投票

struct LessonDetailsViewControllerWrapper: UIViewControllerRepresentable { typealias UIViewControllerType = UIViewController func makeUIViewController(context: UIViewControllerRepresentableContext<LessonDetailsViewControllerWrapper>) -> UIViewController { let viewController = LessonDetailsViewController() return viewController } func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<LessonDetailsViewControllerWrapper>) {} }

然后从 SwiftUI 视图中使用导航链接进行导航:

NavigationLink(destination: LessonDetailsViewControllerWrapper()) { LessonRow(lesson: lesson) }


1
投票

Button(action: { if let vc = self.sb?.instantiateViewController(withIdentifier: "some_identifier") { self.viewObj?.window?.rootViewController = vc // or via present as alternate // self.viewObj?.window?.rootViewController.present(vc, animated: true, completion: nil) } }) {



1
投票

let vc = UIHostingController(rootView: LoginView()) vc.modalPresentationStyle = .fullScreen vc.modalTransitionStyle = .crossDissolve self.present(vc, animated: true)



0
投票

let controller = UIHostingController(rootView: LoginViewController()) self.navigationController?.pushViewController(controller, animated: true)



0
投票
LoginVCControllerRepresentable

传递。 import Foundation import SwiftUI struct LoginVCControllerRepresentable: UIViewControllerRepresentable { typealias UIViewControllerType = UIViewController func makeUIViewController(context: UIViewControllerRepresentableContext<LoginVCControllerRepresentable>) -> UIViewController { let storyboard = UIStoryboard(name: "Main", bundle: nil) let viewController = storyboard.instantiateViewController(withIdentifier: "LogInViewController") as! LogInViewController return viewController } func updateUIViewController(_ uiViewController: UIViewController, context: UIViewControllerRepresentableContext<LoginVCControllerRepresentable>) {} }

	
© www.soinside.com 2019 - 2024. All rights reserved.