Reusing Complex MapBox Navigation UIKit ViewController in SwiftUI

24 views Asked by At

I have an extensive UIKit view controller with many functions that I’m pulling from the Mapbox Navigation SDK example here. I’d like to develop in SwiftUI so I'm learning how to integrate SwiftUI with UIKit. Not sure what my best option is in this scenario.

The view controller has properties and functions that I’d like to expose to my SwiftUI view. Such as a waypoints array property, a boolean property I create for when route preview is showcased, a startNavigation function, requestFollowCamera function e.t.c

In this scenario, I’ve created a UIViewControllerRepresentable above my Viewcontroller such that I can reuse the View in my SwiftUI ContentView and trigger the startNavigation function through a bound state like this:

ViewController.Swift

struct NavViewController: UIViewControllerRepresentable {
  
  @Binding var startNavigation: Bool
        
  func makeUIViewController(context: Context) -> ViewController {
    return ViewController()
  }
  
  func updateUIViewController(_ uiViewController: ViewController, context: Context) {
    if startNavigation{
      uiViewController.startBasicNavigation()
    }
  }
}

ContentView.Swift

struct ContentView: View {
@State var startNavigation: Bool = false

var body: some View {
  ZStack{
    NavViewController(startNavigation: $startNavigation)
    .ignoresSafeArea()
    
    Button("Start Navigation"){
      startNavigation.toggle()
    }
    
  }
  
}
}

But I’d also like to access a show route preview bool from my viewcontroller in SwiftUI. I’m not sure how I might be able to expose the properties in my view controller to swiftUI.

I’m thinking the solution might be to use cordinators, publish properties or observable object. Here's what I've tried doing with no luck: Modified Content View to use an observable object and declared var routeisAvailable:RouteAvailability? of type observable object in my view controller.

struct ContentView: View {
@State var startNavigation: Bool = false

@ObservedObject var routeAvailability: RouteAvailability = RouteAvailability()

var body: some View {
  ZStack{
    NavViewController(startNavigation: $startNavigation)
    .ignoresSafeArea()
    
    
    if routeAvailability.isAvailable{
      Button("Start Navigation"){
        startNavigation.toggle()
      }
    }
  }
  
}
}
0

There are 0 answers