2016-02-28 19 views
6

Sto scrivendo un'app e ho un mapview incorporato per mostrare all'utente la sua posizione. Questo è il mio codice finora:Come posso centrare la mappa sulla posizione dell'utente in rapido?

class YourCurrentLocation: UIViewController, CLLocationManagerDelegate { 

    @IBOutlet weak var mapView: MKMapView! 

    var locationManager = CLLocationManager() 
    let regionRadius: CLLocationDistance = 1000 

    func checkLocationAuthorizationStatus() { 
     if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse { 
      mapView.showsUserLocation = true 
      centerMapOnLocation(locationManager.location!, map: mapView, radius: regionRadius) 
     } else { 
      locationManager.requestAlwaysAuthorization() //requestWhenInUseAuthorization() 
     } 
    } 



    func centerMapOnLocation(location: CLLocation, map: MKMapView, radius: CLLocationDistance) { 
     let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, 
      radius * 2.0, radius * 2.0) 
     map.setRegion(coordinateRegion, animated: true) 
    } 


    override func viewDidLoad() { 
     super.viewDidLoad() 

     // mapView.delegate = self 


     if CLLocationManager.locationServicesEnabled() 
     { 
      //locationManager = CLLocationManager() 
      locationManager.delegate = self 
      locationManager.requestAlwaysAuthorization() 
      locationManager.desiredAccuracy = kCLLocationAccuracyBest 
      locationManager.startUpdatingLocation() 
      print("location enabled") 
      checkLocationAuthorizationStatus()    
     } 
     else 
     { 
      print("Location service disabled"); 
     } 


     // Do any additional setup after loading the view. 
    } 

} 

ho aggiunto anche le due voci al mio plist:

NSLocationAlwaysUsageDescription 
NSLocationWhenInUseUsageDescription 

e anche nel mio Xcode ho impostato per emulare i dati GPS su Londra, Regno Unito.

Quando eseguo l'app, vedo la mappa, ma Londra non è contrassegnata. Che cosa sto facendo di sbagliato?

Btw, ho dovuto commentare questa riga:

//mapView.delegate = self 

in viewDidLoad(), altrimenti ho avuto l'errore:

Cannot assign value of type YourCurrentLocation to type MKMapViewDelegate 

e non sono sicuro se questo è una parte del problema Qui.

Desidero ottenere l'effetto quando visualizzo la mappa dell'utente e un punto contrassegnato su tale mappa con la sua posizione. Puoi aiutarmi con quello?

+0

'locationManager.location!' Nel codice fornirà il simulatore o l'ultima posizione del dispositivo, che potrebbe essere qualsiasi cosa. Nella mia risposta vi mostrerò come usare un 'CLLocationManagerDelegate' per ottenere la posizione dell'utente reale. – paulvs

+0

Ok, vedo ... grazie! un'ultima domanda: cosa accadrà in una situazione in cui il telefono non si trova nel raggio GPS o la posizione non è ancora distinta come quella reale? – user3766930

+0

@ user3766930 potresti contrassegnare la risposta come accettata se risolvesse il tuo problema. – paulvs

risposta

13

Il problema con il codice è che si sta tentando di puntare la mappa sulla posizione dell'utente quando l'utente concede l'autorizzazione alla posizione, non si è in attesa del CoreLocation per fornire all'utente la posizione effettiva. È necessario utilizzare il metodo locationManager(_:didUpdateLocations:) per ricevere la notifica di quando si ottiene la posizione effettiva dell'utente, e è possibile impostare la mappa in modo che punti alla posizione dell'utente.

class ViewController: UIViewController, CLLocationManagerDelegate { 

    @IBOutlet var mapView: MKMapView! 
    var locationManager: CLLocationManager? 

    override func viewDidLoad() { 
     super.viewDidLoad() 

     locationManager = CLLocationManager() 
     locationManager!.delegate = self 

     if CLLocationManager.authorizationStatus() == .AuthorizedWhenInUse { 
      locationManager!.startUpdatingLocation() 
     } else { 
      locationManager!.requestWhenInUseAuthorization() 
     } 
    } 

    func locationManager(manager: CLLocationManager, didChangeAuthorizationStatus status: CLAuthorizationStatus) { 


     switch status { 
     case .NotDetermined: 
      print("NotDetermined") 
     case .Restricted: 
      print("Restricted") 
     case .Denied: 
      print("Denied") 
     case .AuthorizedAlways: 
      print("AuthorizedAlways") 
     case .AuthorizedWhenInUse: 
      print("AuthorizedWhenInUse") 
      locationManager!.startUpdatingLocation() 
     } 
    } 

    func locationManager(manager: CLLocationManager, didUpdateLocations locations: [CLLocation]) { 

     let location = locations.first! 
     let coordinateRegion = MKCoordinateRegionMakeWithDistance(location.coordinate, 500, 500) 
     mapView.setRegion(coordinateRegion, animated: true) 
     locationManager?.stopUpdatingLocation() 
     locationManager = nil 
    } 

    func locationManager(manager: CLLocationManager, didFailWithError error: NSError) { 
     print("Failed to initialize GPS: ", error.description) 
    } 
} 
+0

ok, vedo che hai rifilato molto il mio codice, non sono necessarie le altre linee di codice? – user3766930

+0

btw, c'è un modo per mostrare un pin rosso sulla mappa sulla posizione esatta dell'utente? finora posso vedere solo l'area esatta .. – user3766930

+1

L'impostazione 'kCLLocationAccuracyBest' non è strettamente necessaria perché è il valore predefinito in base alla documentazione, anche se non c'è nulla di male nell'impostarlo. Ho anche aggiornato il controllo di 'authorizationStatus' di' CoreLocation'. – paulvs

Problemi correlati