texasRanger009
texasRanger009

Reputation: 229

SwiftUI and UIKit Interoperability with displaying multiple views

Overview: I'm using SwiftUI, but wanted to use UIKit-MapKit. I used UIViewRepresentable to be able to wrap the UIKit feature.

Problem: I'm learning about swiftui-uikit-interoperability and I'm getting stuck on being able to display multiple SwiftUI views.

Code Snippet:

ContentView

    struct ContentView: View {
    
    @ObservedObject var viewModel: MapView.PinViewModel
    
    init() {
        self.viewModel = MapView.PinViewModel()
    }
    
    var body: some View {
        NavigationView {
            MapView()

            .sheet(isPresented: $viewModel.showPinForm) {
                PinForm()
            }
            
            .navigationTitle("SwiftUI UIKit Interop").scaledToFill()
        }
    }
}

MapView

struct MapView: UIViewRepresentable {

    class PinViewModel: ObservableObject {
        @Published var showPinForm: Bool
        
        init() {
            self.showPinForm = false
        }

        func updateShowPinVar() {
            self.showPinForm = true
        }
    }

    func showPinForm() {
        pinViewModel.updateShowPinVar()
    }

    func makeCoordinator() -> MapViewCoordinator {
        let coordinator = MapViewCoordinator()
        coordinator.delegate = self
        return coordinator
    }
    
    func makeUIView(context: Context) -> MKMapView {
        let mapView = MKMapView()
        mapView.delegate = context.coordinator
        let coordinate = CLLocationCoordinate2D(latitude: 40.7209, longitude: -74.0007)
        let span = MKCoordinateSpan(latitudeDelta: 0.03, longitudeDelta: 0.03)
        let mapRegion = MKCoordinateRegion(center: coordinate, span: span)
        mapView.setRegion(mapRegion, animated: true)
        return mapView
    }
    
    func updateUIView(_ uiView: MKMapView, context: Context) {
    }
}

In this I have a @Published var showPinForm that gets toggled in MapView. ContentView is supposed to watch this variable and when it is true it will cause the sheet to pull up. However, I believe when I enter MapView() from ContentView() then I no longer recognize ContentView.

Using the UIViewRepresentable, what is the best way to display another swiftui view? Does not have to use .sheet (Although, it would be nice)

Upvotes: 0

Views: 332

Answers (1)

Quang Hà
Quang Hà

Reputation: 4746

try to follow this pattern, you can toggle the flag both inside and outside your MapView

struct MapView: UIViewRepresentable {
    @Binding var switcher: Bool // -> use binding
    func makeUIView(context: Context) -> MKMapView { MKMapView() }
    func updateUIView(_ uiView: MKMapView, context: Context) { }
}
struct MainView: View {
    @ObservedObject var viewModel = MainViewModel()
    var body: some View {
        MapView(switcher: $viewModel.flag)
            .sheet(isPresented: $viewModel.flag) {
                Text("Pin pin")
            }
    }
}
class MainViewModel: ObservableObject {
    @Published var flag: Bool = false
}

Upvotes: 0

Related Questions