Cannot get MapView to Zoom in on current location - SWIFT - ios

I have tried all day on this - seems it should be simple - but I cannot get the MapView to zoom in on the current location.
Using "Apple" in the simulator for the location just for testing - I don't get any errors and it runs - but the view just stays at a full picture of the USA with a blue dot - in California representing the Apple location. Any help is appreciated in advance!
Code as follows:
import MapKit
import UIKit
import CoreLocation
class MapViewController: UIViewController, CLLocationManagerDelegate, MKMapViewDelegate {
#IBOutlet weak var mapView: MKMapView!
var locationManager: CLLocationManager!
func createLocationManager () {
locationManager = CLLocationManager()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.distanceFilter = kCLDistanceFilterNone
}
func locationManager (manager:CLLocationManager!, didUpdateLocations locations:[AnyObject]!) {
if let firstlocation = locations.first as? CLLocation {
mapView.setCenterCoordinate(firstlocation.coordinate, animated: true)
let region = MKCoordinateSpanMake (1000,1000)
}
}
override func viewDidLoad() {
super.viewDidLoad()
// Do any additional setup after loading the view.
locationManager = CLLocationManager()
locationManager?.requestWhenInUseAuthorization()
self.mapView.showsUserLocation = true
}

Try Debug->Location->City Bicycle Ride in the simulator. This will give you continual updates.
Also make sure you are setting the locationManager's delegate.

Related

Location Based App using a sliding hamburger menu with buttons that will filter map (iOS MapKit) search results Xcode

I am using MapKit on Xcode to create a "nearby" hospital/mental health center/call center location app. I want the user to be able to filter the map's results. For instance, if I am looking for hospitals, I only want to see hospital locations appear on the map. So far, to do this, I created a sliding hamburger menu with checkbox-like buttons to use as filters. So for example, you tap the hamburger menu button and you check the box with hospitals so that you only get hospital results on the map. However, I must have messed it up somehow because when I get to the MapViewController, only a black screen appears. Please advise how I can fix this or maybe use a different method entirely to achieve the same goal.
import UIKit
import MapKit
class MapViewController: NSObject, CLLocationManagerDelegate {
#IBOutlet weak var mapView: MKMapView!
#IBOutlet weak var trailingMap: NSLayoutConstraint!
#IBOutlet weak var leadingMap: NSLayoutConstraint!
func viewDidLoad() {
mapView.delegate = self as? MKMapViewDelegate
let locationManager = CLLocationManager()
let regionRadius:CLLocationDistance = 1000
locationManager.requestWhenInUseAuthorization()
mapView.showsUserLocation = true
locationManager.startUpdatingLocation()
}
var hamburgerMenuIsVisible = false
#IBAction func hamburgerMenu(_ sender: Any) {
if hamburgerMenuIsVisible {
leadingMap.constant = 150
trailingMap.constant = -150
hamburgerMenuIsVisible = true
} else {
leadingMap.constant = 0
trailingMap.constant = 0
hamburgerMenuIsVisible = false
}
}
var mapItems: [MKMapItem] = []
var place = MKLocalSearch.Request() //user's facility search options
var naturalLanguageQuery: String? {
place.naturalLanguageQuery = "hospital"
let place2 = MKLocalSearch.Request()
place2.naturalLanguageQuery = "Mental Health Facility"
let place3 = MKLocalSearch.Request()
place3.naturalLanguageQuery = "Women's Center"
let place4 = MKLocalSearch.Request()
place4.naturalLanguageQuery = "Call Center"
place.region = self.mapView.region
place2.region = self.mapView.region
place3.region = self.mapView.region
place4.region = self.mapView.region
return place.naturalLanguageQuery
}
#IBAction func hospitalButton(_ sender: Any) {
print(mapItems)
}
#IBAction func callCenterButton(_ sender: Any) {
print(mapItems)
}
}
Your ViewController is subclass of UIViewController, so you have to use inheritance from UIViewController instead of NSObject
So, replace this
class MapViewController: NSObject, CLLocationManagerDelegate {
with this
class MapViewController: UIViewController, CLLocationManagerDelegate {
also fix your viewDidLoad method by adding override keyword before func keyword of your viewDidLoad function. That's because you override function from UIViewController. You will have to call super.viewDidLoad() at the begining of this function. So viewDidLoad should look like this
override func viewDidLoad() {
super.viewDidLoad()
mapView.delegate = self as? MKMapViewDelegate
let locationManager = CLLocationManager()
let regionRadius:CLLocationDistance = 1000
locationManager.requestWhenInUseAuthorization()
mapView.showsUserLocation = true
locationManager.startUpdatingLocation()
}

How do I have Mapbox annotations show up with current location information

I was wondering if anyone may know how to make Mapbox annotations be able show the current location information once dropped on a certain spot. Kind of like it does in Apple's maps when you tap on a pin or drop one and it then shows the locations name or address. I have the code for the pin being dropped but after that I don't know how to make it show information on that current location. Thank you for your feedback in advance.
import UIKit
import CoreLocation
import Mapbox
class SecondViewController: UIViewController, CLLocationManagerDelegate, MGLMapViewDelegate {
#IBOutlet var mapView: MGLMapView!
let manager = CLLocationManager()
#IBOutlet weak var tableView: UITableView!
override func viewDidLoad() {
super.viewDidLoad()
manager.delegate = self
manager.desiredAccuracy = kCLLocationAccuracyBest
manager.requestWhenInUseAuthorization()
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
#IBAction func markStuff(_ sender: Any) {
manager.startUpdatingLocation()
}
func locationManager(_ manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations[0]
let center = CLLocationCoordinate2D(latitude: location.coordinate.latitude, longitude: location.coordinate.longitude)
mapView.setCenter(center, zoomLevel: 15, animated: true)
let annotation = MGLPointAnnotation()
annotation.coordinate = location.coordinate
self.mapView.addAnnotation(annotation)
manager.stopUpdatingLocation()
}
}
You’ll want to reverse geocode the coordinate of the annotation. The Mapbox iOS SDK does not offer this capability out of the box, but we do provide a library called MapboxGeocoder.swift.

Resetting saved map pins, iOS Swift

I am working on a small map application, so far I have the code to drop map pins and save them so they remain once the app is reopened, this class is for the main view controller:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate, UISearchBarDelegate, UIPopoverPresentationControllerDelegate {
var location: CLLocation!
let locationManager = CLLocationManager()
#IBOutlet weak var placesMap: MKMapView!
#IBOutlet weak var addButton: UIBarButtonItem!
#IBOutlet weak var moreStuff: UIButton!
// Popover button action
#IBAction func moreStuff(sender: AnyObject) {
self.performSegueWithIdentifier("showMoreStuff", sender:self)
moreStuff.adjustsImageWhenHighlighted = false
}
#IBAction func addButton(sender: AnyObject) {
let annotation = MKPointAnnotation()
annotation.coordinate = CLLocationCoordinate2D(latitude: self.placesMap.userLocation.coordinate.latitude, longitude: self.placesMap.userLocation.coordinate.longitude)
self.placesMap.addAnnotation(annotation)
self.locationManager.startUpdatingLocation()
}
// Location function
func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) {
let location = locations.last
let center = CLLocationCoordinate2D(latitude: location!.coordinate.latitude, longitude: location!.coordinate.longitude)
let region = MKCoordinateRegion(center: center, span: MKCoordinateSpan(latitudeDelta: 0.004, longitudeDelta: 0.004))
self.placesMap?.setRegion(region, animated: true)
self.locationManager.stopUpdatingLocation()
let locationDictionary:[String:Double] = ["latitude":center.latitude,"longitude":center.longitude]
var locationArray = [[String:Double]]()
if NSUserDefaults.standardUserDefaults().objectForKey("locationArray") != nil {
locationArray = NSUserDefaults.standardUserDefaults().objectForKey("locationArray") as! [[String:Double]]
}
locationArray.append(locationDictionary)
NSUserDefaults.standardUserDefaults().setObject(locationArray, forKey: "locationArray")
NSUserDefaults.standardUserDefaults().synchronize()
}
override func viewDidLoad() {
super.viewDidLoad()
self.locationManager.delegate = self
self.locationManager.desiredAccuracy = kCLLocationAccuracyBest
self.locationManager.requestWhenInUseAuthorization()
self.locationManager.startUpdatingLocation()
self.placesMap?.showsUserLocation = true
if NSUserDefaults.standardUserDefaults().objectForKey("locationArray") != nil {
for dictionary in NSUserDefaults.standardUserDefaults().objectForKey("locationArray") as! [[String:Double]]{
let center = CLLocationCoordinate2D(latitude: dictionary["latitude"]!, longitude: dictionary["longitude"]!)
let annotation = MKPointAnnotation()
annotation.coordinate = center
self.placesMap?.addAnnotation(annotation)
}
}
}
I want to add a button which allows all pins (memories) to be reset at once. This button is located on a new scene and class, called "PopoverOptions". I have the following code from the class which should do this, but it does not seem to be functioning as no pins disappear from the map once it is pressed by the user!
#IBOutlet weak var resetMemories: UIButton!
#IBAction func resetMemories(sender: AnyObject) {
func removeStoredLocations(){
NSUserDefaults.standardUserDefaults().removeObjectForKey("locationArray")
NSUserDefaults.standardUserDefaults().synchronize()
}
}
Any idea why the pins aren't being removed? I have ensured that the class is linked correctly as well as the buttons outlet / action.
You clear out your user defaults key, but don't change the map view on the view controller that shows those pins. You need to call removeAnnotations to remove the annotations from the map.
You could add a viewWillAppear method that detects that your annotations have been deleted and remove them. Something like this:
func viewWillAppear(_ animated: Bool)
{
if NSUserDefaults.standardUserDefaults().objectForKey("locationArray") == nil
{
if let annotations = self.placesMap.annotations
self.placesMap?.removeAnnotations(annotations)
}
}
The code above is written to only remove the annotations from the map if the entire annotations dictionary was deleted from userDefaults. That way you avoid reloading the annotations every time the view controller regains focus.
BTW, you said your new scene is called "PopoverOptions." If the scene is presented in a popover then the above might not work. (I don't think viewWillAppear gets called on a view controller when a popover is dismissed, but I don't remember for sure.)

I want to access a var in a second view controller in swift code

Hi here is my code so far
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet var map: MKMapView!
var locationManager = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
var userLocation:CLLocation = locations[0] as! CLLocation
var latitude = userLocation.coordinate.latitude
var longitude = userLocation.coordinate.longitude
var latDelta:CLLocationDegrees = 0.05
var lonDelta:CLLocationDegrees = 0.05
var span:MKCoordinateSpan = MKCoordinateSpanMake(latDelta, lonDelta)
var location:CLLocationCoordinate2D = CLLocationCoordinate2DMake(latitude, longitude)
var region:MKCoordinateRegion = MKCoordinateRegionMake(location, span)
self.map.setRegion(region, animated: false)
println(latitude)
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
I would like to access the info in the locationManager function in a second view controller showing the latitude, longitude, course and speed. Am a newbie so any help would be great. cheers
Move your variables you want to pass to the second VC from local to class-scope:
import UIKit
import MapKit
import CoreLocation
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet var map: MKMapView!
var locationManager = CLLocationManager()
var longitude:CLLocationDegrees!
var latitude:CLLocationDegrees!
override func viewDidLoad() {
super.viewDidLoad()
locationManager.delegate = self
locationManager.desiredAccuracy = kCLLocationAccuracyBest
locationManager.requestWhenInUseAuthorization()
locationManager.startUpdatingLocation()
}
Create your Target UIViewController with variables to hold the passed values:
import UIKit
import MapKit
import CoreLocation
class MyDestinationViewController: UIViewController {
var longitude:CLLocationDegrees!
var latitude:CLLocationDegrees!
override func viewDidLoad() {
super.viewDidLoad()
}
}
Add the prepareForSegue method to your viewcontroller from which you want to send the data:
override func prepareForSegue(segue: UIStoryboardSegue, sender: AnyObject?) {
let destinationVC = segue.destinationViewController as! MyDestinationViewController
destinationVC.latitude = latitude
destinationVC.longitude = longitude
}
If you do not want to use a segue, you can just instanciate the targetViewController and pass the variables, before presenting the VC.

Location Data from CoreLocation swift

I'm trying to get the users coordinates, but I cant work out how to retrieve them? Here is my code for finding their location on a map, what should I add to get numerical values for longitude/latitude? It works fine, and I've added the requestAuthorization key into info.plist.I've tried using the CLLocation object, but I cant seem to get it to work.
import UIKit
import MapKit
class ViewController: UIViewController, MKMapViewDelegate, CLLocationManagerDelegate {
#IBOutlet weak var Map: MKMapView!
var locationMgr = CLLocationManager()
override func viewDidLoad() {
super.viewDidLoad()
locationMgr.delegate = self
locationMgr = CLLocationManager()
locationMgr.requestAlwaysAuthorization()
locationMgr.startUpdatingLocation()
Map.showsUserLocation = true
}
override func didReceiveMemoryWarning() {
super.didReceiveMemoryWarning()
}
}
Implement the CLLocationManager delegate protocol methods, specifically:
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!)
You've initialised the location manager twice. so the delegate you set after first time the manager initialised is nil. so delete this locationMgr = CLLocationManager() in your viewDidLoad method. it should work

Resources