Krneki123
Krneki123

Reputation: 77

Allow users to move around the map while displaying their location

I want to allow users to zoom in/out and move freely around the map while the app is tracking and displaying their current location. Later i will try to add a button that you can press and it will move you back to the center of user location. I think the problem is that in my LocationManager file i am creating new region everytime i get a new location coordinates. But i do not know any other ways of tracking user location and displaying it.

LocationManager:

import Foundation
import CoreLocation
import MapKit

class LocationManager: NSObject, ObservableObject, CLLocationManagerDelegate{
    let locationManager = CLLocationManager()
    @Published var location: CLLocationCoordinate2D?
    @Published var region = MKCoordinateRegion()
    
    override init(){
        super.init()
        locationManager.delegate = self
    }
    
    func startTracking() {
        locationManager.requestAlwaysAuthorization()
        locationManager.desiredAccuracy = kCLLocationAccuracyBest
        locationManager.distanceFilter = kCLDistanceFilterNone
        locationManager.allowsBackgroundLocationUpdates = true
        locationManager.startUpdatingLocation()
    }
    
    func stopTracking() {
        print("stop test")
        locationManager.stopUpdatingLocation()
        locationManager.allowsBackgroundLocationUpdates = false
    }
    
    func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
        let tempLocation = locations.last?.coordinate
        print(tempLocation)
        
        let center = CLLocationCoordinate2D(latitude: tempLocation?.latitude ?? 0.0, longitude: tempLocation?.longitude ?? 0.0)
        let span = MKCoordinateSpan(latitudeDelta: 0.5, longitudeDelta: 0.5)
        let tempRegion = MKCoordinateRegion(center: center, span: span)
        
        DispatchQueue.main.async {
            self.location = tempLocation
            self.region = tempRegion
        }
    }
}

ContentView:

import SwiftUI
import MapKit

struct ContentView: View {
    @State var isButtonPressed: Bool = false
    @StateObject var locationManager = LocationManager()
    var body: some View {
        VStack{
            Button("START"){
                isButtonPressed = true
                locationManager.startTracking()
            }
            
            Button("STOP"){
                isButtonPressed = false
                locationManager.stopTracking()
            }
            
            mapView(isButtonPressed: isButtonPressed, manager: locationManager)
        }
    }
}


struct mapView: View{
    var isButtonPressed: Bool
    @ObservedObject var manager: LocationManager
    
    @State var defaultRegion = MKCoordinateRegion(center: CLLocationCoordinate2D(latitude: 0, longitude: 0), latitudinalMeters: 1000, longitudinalMeters: 1000)
    
    var body: some View{
        if isButtonPressed == true{
            if let location = manager.location {
                Map(coordinateRegion: $manager.region, interactionModes: .all, showsUserLocation: true, userTrackingMode:nil)
            } else{
                Map(coordinateRegion: $defaultRegion)
            }
        }
        else
        {
            Map(coordinateRegion: $defaultRegion)
        }
        
    }
}

Thanks!

Upvotes: 0

Views: 746

Answers (1)

Duncan C
Duncan C

Reputation: 131481

Creating a series of regions is the wrong way to monitor the user's location.

It's been quite a while since I've written a mapping app, but here's the general idea of what you should do:

Create an instance of the location manager.

Set yourself as the location manager's delegate.

Ask the user for permission to get location updates while your app is running (if you don't have permission already.)

Call startUpdatingLocation() to request location updates

Respond to calls to the location manager delegate's locationManager(_:didUpdateLocations:) method as needed. (If you set up the map to show the user's location you won't have to do anything special - the blue dot will update automatically.)

Upvotes: 0

Related Questions