【问题标题】:How to Navigating from SwiftUI View to UIKit UIViewController如何从 SwiftUI 视图导航到 UIKit UIViewController
【发布时间】:2020-06-03 23:48:34
【问题描述】:

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

我已经能够通过点击按钮从 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 视图,然后调用执行与上述代码类似的操作来更改当前视图控制器。但是,在模拟器上尝试时没有任何反应。
  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 集成到 UIKitNOT 反过来,我不确定 UIViewControllerRepresentable 是否是这个问题的答案。非常感谢对此的任何解决方案、替代方案或有用的知识。再次感谢!

【问题讨论】:

  • 嗨,Chiah,我也遇到了类似的情况。你能找到解决办法吗?
  • 嘿!不幸的是,我无法克服这个问题。由于我的应用程序相对较小,因此我只是在 SwiftUI 中重新编写了所有内容(老实说,这非常好!)。对不起!

标签: swift uiviewcontroller uikit swiftui swiftui-navigationlink


【解决方案1】:

喏,

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

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

【讨论】:

  • 同样,我提到过这个尝试过,它在模态呈现 SwiftUI 视图时有效,但如果我想正确过渡则不起作用(即不是模态,覆盖整个屏幕并且不能滑动下)!
【解决方案2】:

你也可以这样做,只是按照镜像顺序,比如跟随(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)
        }
    }) {

【讨论】:

  • 嗨,正如我所提到的,我试过这个(然后又试了一次),但点击按钮时没有任何反应!
【解决方案3】:

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

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

【讨论】:

    【解决方案4】:

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

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

    【讨论】:

      猜你喜欢
      • 2021-04-06
      • 2020-06-19
      • 1970-01-01
      • 2021-05-25
      • 2021-08-09
      • 2021-12-04
      • 2020-01-17
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多