Thomas Clayson
Thomas Clayson

Reputation: 29925

Why is MKMapView putting me in the sea?

I have this code to set the map at the user's location:

MKCoordinateSpan span;
span.latitudeDelta=0.2;
span.longitudeDelta=0.2; 

CLLocationCoordinate2D location=mapView.userLocation.coordinate;
location = mapView.userLocation.location.coordinate;

MKCoordinateRegion region;
region.span=span;
region.center=location;

[mapView setRegion:region animated:TRUE];
[mapView regionThatFits:region];

Now when I do mapView.showsUserLocation=YES it shows my location at the right place (on my device, and the apple hq in the simulator) however, both times the code above puts me in the sea somewhere near africa!

Any ideas?

Upvotes: 7

Views: 3005

Answers (4)

Fidel
Fidel

Reputation: 1183

I am answering this question because the answer picked did not really help me and I was having the exact same issue. didUpdateUserLocation is not very practical because it makes the app update every single time the location changes. The other issue with the above solution is that when the map loads it's still too early to ask for a location. So how do you ask for user location before the the map loads so that the zooming doesn't take you to Africa?

You need to request the location by using the location manager on the viewDidLoad. Then after that you can set the region.

SWIFT 3

   //top of your class
   let locManger  = CLLocationManager()


   override func viewDidLoad()   {
        super.viewDidLoad()


         //request user location
         locManager.startUpdatingLocation()


        //this is the code that sets the region based on the location

        let span = MKCoordinateSpanMake(0.5, 0.5)

        let location = CLLocationCoordinate2DMake((locManager.location?.coordinate.latitude)!, (locManager.location?.coordinate.longitude)!)

        let region = MKCoordinateRegionMake(location, span)

        yourMap.setRegion(region, animated: false)


        //stop location updating 
        locManager.stopUpdatingLocation()
 }

Upvotes: 0

Atef
Atef

Reputation: 2902

You can choose this method..

- (void)mapView:(MKMapView *)_mapView regionDidChangeAnimated:(BOOL)animated{

CLGeocoder *ceo = [[CLGeocoder alloc]init];
CLLocation *loc = [[CLLocation alloc]initWithLatitude:_mapView.region.center.latitude longitude:_mapView.region.center.longitude];
CLLocationAccuracy accuracy = _mapView.userLocation.location.horizontalAccuracy;

if (accuracy) {
    current_pickup_location = loc;
    [_currentStreetSpinner startAnimating];
    [ceo reverseGeocodeLocation:loc
              completionHandler:^(NSArray<CLPlacemark *> * _Nullable placemarks, NSError * _Nullable error){
                  CLPlacemark *placemark = [placemarks objectAtIndex:0];
                  NSString *locatedAt = [[placemark.addressDictionary valueForKey:@"FormattedAddressLines"] componentsJoinedByString:@", "];
                  //                  NSLog(@"location %@",placemark.location);
                  NSLog(@"I am currently at %@",locatedAt);
                  _currentStreetLabel.text = locatedAt;
                  static_iVar = _currentStreetLabel.text;
                  [_currentStreetSpinner stopAnimating];
                  [self listDoctorsWithSpeciality_id:currentSpeciality_id
                               withProfessionalityId:currentProfessionality_id];
              }];
}

}

Upvotes: 0

What I have done was add the following entry on info.plist:

NSLocationAlwaysUsageDescription

Got this info into this (very good) tutorial: https://www.youtube.com/watch?v=Z272SMC9zuQ

Upvotes: 0

Dan Ray
Dan Ray

Reputation: 21893

The latitude/longitude pair 0/0 is on the equator due south of Greenwich, England. That spot is in the Gulf of Guinea, off the West coast of Africa. If that's where your pin is getting placed, then your mapView.userLocation isn't getting set.

Probably your code here is running before MKMapKit has had a chance to get its location. What you really want to do is have your viewController adopt the MKMapKitDelegate protocol, set the .delegate property of your map view to self, and then implement the method:

- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation

That method will get called when the map kit locates the user, and you can use the userLocation value you get passed there to set the region on the map. Until that gets called the first time, though, the MapView is still working on locating itself, and your asking about its location is premature.

Also, your regionThatFits there at the end is a no-op. That method doesn't resize the region in place, it actually returns a resized region, for you to use however you will. So you want to set your map view's region to what that method returns. Like this:

[mapView setRegion:[mapView regionThatFits:region] animated:TRUE];

Upvotes: 15

Related Questions