我有一个 UiKit 应用程序,使用 UIHostingController
来显示 SwiftUI View 。在此 View 中有一个按钮,我想用它导航到另一个 ViewController。 如何从 SwiftUI View 内部推送新的 viewController?(或者更一般地说:如何从 SwiftUI View 内部从 ViewController 调用函数?)
当然,我可以只在 SwiftUI 中使用 NavigationView,但我想使用 UiKit 完成大部分工作,以便业务逻辑和 UI 之间实现清晰分离。
import UIKit
import SwiftUI
class MainViewController: UIViewController {
var viewModel = ViewModel()
override func viewDidLoad() {
super.viewDidLoad()
addView()
}
func addView() {
let testView = SwiftUIView(viewModel: viewModel)
let controller = UIHostingController(rootView: testView)
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(controller.view)
controller.didMove(toParent: self)
NSLayoutConstraint.activate([
controller.view.widthAnchor.constraint(equalTo: view.widthAnchor),
controller.view.heightAnchor.constraint(equalTo: view.heightAnchor),
controller.view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
controller.view.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
func navigate() { // how do I call this from inside SwiftUI testView view?
let otherView = Text("test")
let nextVc = UIHostingController(rootView: otherView)
navigationController?.pushViewController(nextVc, animated: true)
}
}
SwiftUI 类似于:
import SwiftUI
struct SwiftUIView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
Button {
// push new view controller
} label: {
Text("go")
}
}
}
最佳答案
将 MainViewController 设置为 ObservableObject
在testView
上设置环境对象
使用 @EnvironmentObject var Parent: MainViewController 访问 View 内的环境对象
class MainViewController: UIViewController, ObservableObject {
var viewModel = ViewModel()
override func viewDidLoad() {
super.viewDidLoad()
addView()
}
func addView() {
let testView = SwiftUIView(viewModel: viewModel)
let controller = UIHostingController(rootView: testView.environmentObject(self))
addChild(controller)
controller.view.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(controller.view)
controller.didMove(toParent: self)
NSLayoutConstraint.activate([
controller.view.widthAnchor.constraint(equalTo: view.widthAnchor),
controller.view.heightAnchor.constraint(equalTo: view.heightAnchor),
controller.view.centerXAnchor.constraint(equalTo: view.centerXAnchor),
controller.view.centerYAnchor.constraint(equalTo: view.centerYAnchor)
])
}
}
struct SwiftUIView: View {
@EnvironmentObject var parent: MainViewController
var body: some View {
Button {
// push new view controller
parent.navigationController?.pushViewController(<#T##viewController: UIViewController##UIViewController#>, animated: <#T##Bool#>)
} label: {
Text("go")
}
}
}
关于ios - 如何使用pushViewController从UIHostingController的SwiftUI View 内部推送ViewController?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75627630/