iosswiftswiftuiuihostingcontroller

Present a UIViewController from a UIHostingViewController


I'm starting to rebuild my app from Swift to SwiftUI.

I have one UIViewController that is built using UIPresentationController and has custom drag gestures that I would like to use as-is (for now).

I'm trying to figure out if I am able to present this from my SwiftUI View.

Here is how I navigate to the SwiftUI view:

let dataStore = DataStore()
let vc = Host(rootView: SwiftUIView(store: dataStore))
self.navigationController?.pushViewController(vc, animated: true)
 

The method to present my controller is in my DataStore.

Here is what I am trying:

func displayDetailController(forData data: Data?) {
     let height = // I set a custom height here as I can drag 
     //this view to pop to the middle, to the top, or dismiss
     guard let dat = data else { return }
     let const = DetailViewController.Constructor(data: dat)
     let vc = DetailViewController.loadFromNib(constructor: const, height: height) 
        
     let hostingController = Host(rootView: SwiftUIView(store: self))
     hostingController.navigationController?.present(vc, animated: true)
}

I have a Button that when tapped will call displayDetailController but nothing happens.

The goal being my DetailViewController is presented and I can see my data and use the drag gestures.


Solution

  • Right now, you're creating a new Host and SwiftUIView and trying to present from them. But, they aren't part of the view hierarchy, so nothing gets presented.

    Instead, you probably want to pass a reference to your actual view controller. This code is incomplete, since you didn't include definitions for everything, but it should get you started:

    let dataStore = DataStore()
    dataStore.navigationController = self.navigationController
    let vc = Host(rootView: SwiftUIView(store: dataStore))
    self.navigationController?.pushViewController(vc, animated: true)
    
    class DataStore {
      var navigationController : UINavigationController?
    
      // other code
    
      func displayDetailController(forData data: Data?) {
         let height = 100
         guard let dat = data else { return }
         let const = DetailViewController.Constructor(data: dat)
         let vc = DetailViewController.loadFromNib(constructor: const, height: height) 
         self.navigationController?.present(vc, animated: true)
      }
    }