繁体   English   中英

如何从 SwiftUI 视图导航到 UIKit UIViewController

[英]How to Navigating from SwiftUI View to UIKit UIViewController

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

我已经能够做到这一点,从 UIViewController 导航到 SwiftUI 点击按钮查看:

    @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 视图过渡到 UIViewController?(因为应用程序的 rest 在 UIKit 中)? 我在 SwiftUI 视图中有一个按钮,点击它可以导航回 UIViewController。 我试过了:

  1. viewstoryboard对象传递给 SwiftUI 视图,然后调用执行类似于上述代码的操作以更改当前视图 controller。但是,在模拟器上尝试时没有任何反应。
  2. 使用.present以模态方式显示 SwiftUI 视图。 这有效,我可以允许 SwiftUI View .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是否是这个问题的答案。 非常感谢对此的任何解决方案、替代方案或有用的知识。 再次感谢!

再见,

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

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)
}

你可以做同样的事情,只能按照镜像顺序,比如跟随(scratchy)......

    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)
        }
    }) {

将您的 UIViewController 包装到 UIViewControllerRepresentable 包装器。

 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) }

您可以更改演示样式和过渡样式以全屏显示控制器

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

这是来自 UIKit Button Press 的推送导航控制器的示例

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM