Prevent zooming/heading update stop in iOS MKMapView - ios

In iOS I have an MKMapView and CLLocationManager to update the heading and location. No matter what I do, I can't get the map view to stop zooming in tightly on the user's location. I have annotations on the map that I want visible at all times, and I want the heading to update as the user spins the device. This is working using mapView.setRegion, but after a bit, the map locks at the north and no longer rotates. Below is the CLLocationManager code I'm using:
func locationManager(_ manager: CLLocationManager, didUpdateHeading newHeading: CLHeading) {
if data != nil{
setRegion(locationManager?.location?.coordinate.latitude)!, longitude: (locationManager?.location?.coordinate.longitude)!), data: data!)
}
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if !regionSet && data != nil{
setRegion(location: CLLocationCoordinate2D(latitude: (locationManager?.location?.coordinate.latitude)!, longitude: (locationManager?.location?.coordinate.longitude)!), data: data!)
regionSet = true
}
}
setRegion calculates the extents of the map to zoom on and sets the setRegion function appropriately.
Below is setRegion. I calculate the zoomWindowDegrees variable when I load in the annotations by finding the maximum lat/long for the annotations and the use that in the function.
private func setRegion(location:CLLocationCoordinate2D, towers:[Tower]){
let center = location
let coordinateSpan = MKCoordinateSpan(latitudeDelta: zoomWindowDegrees, longitudeDelta: zoomWindowDegrees)
let region = MKCoordinateRegion(center: center, span: coordinateSpan)
mapView.setRegion(region, animated: false)
}

Related

How to update my location Custom Marker with googleMaps in Swift

I am currently trying to create a method to change the blue dot of googlemaps with a custom Icon, but currently I have the problem that the marker prints but don't clear its last location, this is the code I am using right now on with the "CLLocationManagerDelegate" and "GMSMap"
//MARK: - location delegate methods
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
if userLocation == nil {
userLocation = manager.location!.coordinate
let location = GMSCameraPosition.camera(withLatitude: userLocation.latitude, longitude: userLocation.longitude, zoom: 15)
mapView.animate(to: location)
}
userLocation = manager.location!.coordinate
let userLocationMarker = GMSMarker(position: manager.location!.coordinate)
userLocationMarker.icon = UIImage(named: "est-my-location")
userLocationMarker.map = mapView
}
Get Last Location from didUpdateLocations locations and update marker position.
Try Doing it this Way:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let newLocation = locations.last // find your device's Last location
let position = GMSCameraPosition.camera(withTarget: newLocation!.coordinate, zoom: 15.0) // show your device location on map
mapView.animate(to: position)
let lat = (newLocation?.coordinate.latitude)! // get current location latitude
let long = (newLocation?.coordinate.longitude)! //get current location longitude
userLocationMarker.icon = UIImage(named: "est-my-location")
userLocationMarker.position = CLLocationCoordinate2DMake(lat,long)
DispatchQueue.main.async {
userLocationMarker.map = mapView // Setting marker on mapview in main thread.
}
}

Mapkit - Swift4 - How to disable Auto zooming

Apologies for the absurdely junior question but for some reason I can't grasp how to stop this from happening.
When I run the app, and I pinch to zoom into the map (or out, or navigate away from my position) the app will always pull me back to a set height and to my location. I'd like to not have this happen and just have the experience of zooming to whatever level and moving around without being interrupted.
Any ideas?
Here's the code snip from my VC:
let regionRadius: CLLocationDistance = 2000
func centerMapOnLocation(location: CLLocation) {
let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, regionRadius, regionRadius)
mapView.setRegion(coordinateRegion, animated: true)
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
let center = location.coordinate
let span = MKCoordinateSpan(latitudeDelta: 0.05, longitudeDelta: 0.05)
let region = MKCoordinateRegion(center: center, span: span)
mapView.setRegion(region, animated: true)
mapView.showsUserLocation = true
}
Thanks for any help
Location Manager delegate methods can be called very frequently and at any time. So you need to stop updating locations.
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
manager.stopUpdatingLocation()
manager.delegate = nil
let location = locations[0]
...
}

Retain map zoom level while there is a change in location

I am using a MKMapView application. but when zoom into the map to the current user location, the map zooms well. But when there is a change in current location, the map automatically zooms out to the original position where it all started. How can I retain the same level of zoom even when the location changes. Thank you.
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let latestlocation:CLLocation = locations[locations.count-1]
let a = latestlocation.coordinate.latitude
let b = latestlocation.coordinate.longitude
let center = CLLocationCoordinate2D(latitude: a, longitude: b)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpanMake(0.05, 0.05))
self.mapView.setRegion(region, animated: false)
mapView.setUserTrackingMode(.follow, animated: true)
self.mapView.showsUserLocation = true
}

ios mapkit, carrier name crash with [LogMessageLogging] 6.1 Unable to retrieve CarrierName

I have added MapKit in my app. I have connected MKmapview to my viewcontroller by IBOUTLET, it runs fine in simulator but it crashes in my device with this
[LogMessageLogging] 6.1 Unable to retrieve CarrierName. CTError: domain-2, code-5, errStr:((os/kern) failure).
I am taking user's location from CLLocationmanager and trying to add annotation in the map. Code is as below:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let userLocation:CLLocation = locations[0] as CLLocation
let coordinate = CLLocationCoordinate2D(latitude: userLocation.coordinate.latitude, longitude: userLocation.coordinate.longitude)
MD_myCurrentLocation = coordinate
setupLocationMarker(coordinate:coordinate)
manager.stopUpdatingLocation()
}
func setupLocationMarker(coordinate: CLLocationCoordinate2D) {
iosMap.removeAnnotations(iosMap.annotations)
let span = MKCoordinateSpanMake(0.01, 0.01)
let region = MKCoordinateRegion(center: coordinate, span: span)
iosMap.setRegion(region, animated: true)
let annotation = MKPointAnnotation()
annotation.coordinate = coordinate
iosMap.addAnnotation(annotation)
}
Try resetting your device's network configuration by going to >> Settings >> General >> Reset >> Reset Network Settings.
Or
import CoreTelephony in AppDelegate
Hope this helps.

Loading user location data for GeoFire query in viewWillAppear

On my main CollectionView (the app home page), I would like to update the locations (i.e. the cells themselves) based on the closest location to the user. I am storing my locations in Firebase and will be using GeoFire and core location in order to properly list out the locations in distance order from the user.
Other posts have said that the best practice for observers involves loading it in viewWillAppear; however, I have been unable to obtain the user's location before this runs and do not have a centered point for my GeoFire query. Most examples related to CoreLocation involve maps or preselected coordinates, but I wasn't planning on using a map within this controller and want to dynamically load based off of user location.
I have researched loading didUpdateLocations within AppDelegate, but have not been able to call that method there either. What is the best way to get user location coordinates before running a GeoFire query when loading that returned data in viewWillAppear or do you need to set a region and check if a user has entered within that region?
var locationDict = [CLLocation]() //using this variable to pass values outside the function to the query
override func viewWillAppear(animated: Bool) {
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestAlwaysAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let recentLocation = locations[0]
locationDict.append(recentLocation)
}
func locationManager(_ manager: CLLocationManager, didFailWithError error: Error) {
print(error.localizedDescription)
}
There is quite a lot missing in your code, but in short (what works for me):
.requestLocation in viewWillAppear
.startUpdatingLocation() in viewDidAppear. (so twice).
var justStartedUsingMap = true
In didUpdateLocations:
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]){
guard let myLocation:CLLocation = manager.location else {return}
let location:CLLocationCoordinate2D = myLocation.coordinate
let region = MKCoordinateRegion(center: location, span: MKCoordinateSpan(latitudeDelta: 0.12, longitudeDelta: 0.12))
if justStartedUsingMap == true {
self.currentLocationSearch(myLocation)
justStartedUsingMap = false
} else {
locationManager.stopUpdatingLocation()
}
self.map.setRegion(region, animated: true)
}
func currentLocationSearch(_ location: CLLocation) {
// the geofire observer
}

Resources