如何从SwiftUI视图导航到UIKit UIViewController

w8rqjzmb  于 2023-02-03  发布在  Swift
关注(0)|答案(5)|浏览(264)

到目前为止,我有一个完全使用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?(因为应用程序的其余部分在UIKit中)?我在SwiftUI视图中有一个按钮,点击它可以导航回UIViewController。我尝试过:
1.将viewstoryboard对象传递给SwiftUI视图,然后调用,执行类似于上述代码的操作,以更改当前视图控制器。但是,在模拟器上尝试时,没有任何React。
1.使用.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是否是这个问题的答案。非常感谢对此问题的任何解决方案、替代方案或有用的知识。再次感谢!

q43xntqr

q43xntqr1#

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

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

de90aj5v2#

你可以做同样的事情,只是在镜像顺序,像下面(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)
        }
    }) {
m3eecexj

m3eecexj3#

您可以更改显示样式和转换样式以全屏显示控制器

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

8xiog9wr4#

将UIViewController Package 为UIViewControllerRepresentable Package 器。

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

kse8i1jr5#

以下是UIKit Button Press的推送导航控制器示例

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

相关问题