How can I add a working search bar with autocomplete to my SwiftUI MapKit map?

Viewed 32

I've followed a few tutorials to make a map and have the map centered on my current location. For the app I'm developing, I would also like to have a search bar just like Apple Maps does. I would like to have a map that's initially centered on the user's current location, but they can enter an address and view addresses in that area.

Here is my map UI:

import SwiftUI
import MapKit

struct MapSubView: View {
    // 2.
    @StateObject private var viewModel = MapSubViewModel()

    var body: some View {
        // 3.
        Map(coordinateRegion: $viewModel.region, showsUserLocation: true)
            .edgesIgnoringSafeArea(.all)
            .accentColor(Color(.systemBlue))
            .onAppear{
                viewModel.checkIfLocationServicesIsEnabled()
            }
    }
}

struct MapSubView_Previews: PreviewProvider {
    static var previews: some View {
        MapSubView()
    }
}

And here is the code for the current location:

import Foundation
import SwiftUI
import MapKit

enum MapDetails {
    static let startingLocation = CLLocationCoordinate2D(
        latitude: 33.54374587046632,
        longitude: -117.785453016537693)
    static let defaultSpan = MKCoordinateSpan(
        latitudeDelta: 0.002,
        longitudeDelta: 0.002)
}

final class MapSubViewModel: NSObject, ObservableObject, CLLocationManagerDelegate {
    
    @Published var region = MKCoordinateRegion(
        center: MapDetails.startingLocation,
        span: MapDetails.defaultSpan)
    
    var locationManager: CLLocationManager?
    
    func checkIfLocationServicesIsEnabled() {
        if CLLocationManager.locationServicesEnabled() {
            locationManager = CLLocationManager()
            locationManager!.delegate = self

        } else { print("Enable Location Services")
            
        }
    }
    
    private func checkLocationAuthorization(){
        guard let locationManager = locationManager else { return }
        
        switch locationManager.authorizationStatus {
            
        case .notDetermined:
            locationManager.requestWhenInUseAuthorization()
        case .restricted:
            print("Your Location Services is Restricted")
        case .denied:
            print("Enable Location Services in System Settings")
        case .authorizedAlways, .authorizedWhenInUse:
            region = MKCoordinateRegion(center: locationManager.location!.coordinate,
                        span: MKCoordinateSpan(latitudeDelta: 0.002, longitudeDelta: 0.002))
        @unknown default:
            break
        }

    }
    
    func locationManagerDidChangeAuthorization(_ manager: CLLocationManager) {
        checkLocationAuthorization()
        
    }
}
0 Answers
Related