2
votes

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

1
SwiftUI does not work with UINavigationController, so you need to continue using UIKit to navigate in such scenario.Asperi
how would i do that from a button in swiftui. i made an edit on the code.let say i have a button there, how would u do that from its actionj.doe

1 Answers

1
votes

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