到目前为止,我有一个完全使用 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。我试过了:
view
和 storyboard
对象传递给 SwiftUI View,然后调用执行类似于上面代码的操作来更改当前视图控制器。然而,当在模拟器上尝试时,没有任何反应。.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
是否是这个问题的答案。任何对此问题的解决方案、替代方案或有用的知识都非常感激。再次感谢!
我尝试通过使用闭包回调来遵循你的方法。
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)
}
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)
}
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)
}
}) {
let vc = UIHostingController(rootView: LoginView())
vc.modalPresentationStyle = .fullScreen
vc.modalTransitionStyle = .crossDissolve
self.present(vc, animated: true)
let controller = UIHostingController(rootView: LoginViewController())
self.navigationController?.pushViewController(controller, animated: true)
传递。
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>) {}
}