I have a UiKit app using a UIHostingController
to show a SwiftUI view. In this view there is a button, which I want to use to navigate to another ViewController. How can I push a new viewController from inside this SwiftUI view? (or more generally: how can I call a function from my ViewController from inside the SwiftUI view?)
Of course I could just NavigationView inside SwiftUI, but I want to do most with UiKit, in order to have clean separation between business logic and 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)
}
}
with the SwiftUI being something like:
import SwiftUI
struct SwiftUIView: View {
@ObservedObject var viewModel: ViewModel
var body: some View {
Button {
// push new view controller
} label: {
Text("go")
}
}
}
2
Answers
call this function on your button-click event. try to make this function global so you can access it from every swiftUI View.
Make your MainViewController as ObservableObject
Set environment object on
testView
Access your environment object inside your view using
@EnvironmentObject var parent: MainViewController