Reputation: 305
i have a navigation controller which navigates to a view controller, which navigates to uihostingcontroller. How would i push to another view controller from swift ui
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = (scene as? UIWindowScene) else { return }
self.window = UIWindow(frame: windowScene.coordinateSpace.bounds)
window?.windowScene = windowScene
let navigationView = UINavigationController(rootViewController: PreviewViewVideoController())
navigationView.isToolbarHidden = true
self.window?.rootViewController = navigationView
self.window?.makeKeyAndVisible()
}
in preview video controller
func tableView(_ tableView: UITableView, didSelectRowAt indexPath: IndexPath) {
switch cards[indexPath.row] {
case .trans_human:
let controller = UIHostingControllerCustom(rootView: FilmOverviewView(overview: TransHumanOverview()))
self.navigationController?.pushViewController(controller, animated: true)
controller.navigationItem.title = cards[indexPath.row].rawValue
}
}
in filmOverviewView
struct FilmOverviewView: View {
var filmOverview: FilmOverview!
var imageResource: String!
init(overview: FilmOverview) {
filmOverview = overview
}
var body: some View {
ScrollView(Axis.Set.vertical, showsIndicators: false) {
VStack {
Image(filmOverview.imageResource)
.resizable()
.frame(width: UIScreen.main.bounds.width,
height: UIScreen.main.bounds.height / 2)
.overlay(StartButtonOverlay(), alignment: .bottom)
Button(action: {})
}
}
How would i navigate from a swiftui button view action to a new view controller using existing navigation stack
Upvotes: 2
Views: 2845
Reputation: 258365
I would inject UINavigationController
into SwiftUI stack via environment values
struct NavigationControllerKey: EnvironmentKey {
static let defaultValue: UINavigationController? = nil
}
extension EnvironmentValues {
var navigationController: NavigationControllerKey.Value {
get {
return self[NavigationControllerKey.self]
}
set {
self[NavigationControllerKey.self] = newValue
}
}
}
then in table view delegate inject it
let controller = UIHostingControllerCustom(rootView:
FilmOverviewView(overview: TransHumanOverview()
.environment(\.navigationController, self.navigationController))
and now in FilmOverviewView
we can use it
struct FilmOverviewView: View {
@Environment(\.navigationController) var navigationController
// ... other code
var body: some View {
ScrollView(Axis.Set.vertical, showsIndicators: false) {
VStack {
// ... other code
Button("Demo") {
let controller = UIHostingControllerCustom(rootView:
SomeOtherView() // inject if needed again
.environment(\.navigationController, self.navigationController)))
self.navigationController?.pushViewController(controller, animated: true)
}
}
}
Update: updated custom hosting controller
class UIHostingControllerCustom<V: View>: UIHostingController<V> {
override func viewWillAppear(_ animated: Bool) {
navigationController?.setNavigationBarHidden(true, animated: false)
}
}
Upvotes: 3