问题
I've created a test application with only one view containing an MKMapView and a controller which acts as the MapView's delegate.
When I do a fresh build (removed from the device completely before re-installing) and log the callbacks, I can see that mapView:didUpdateUserLocation
is called twice before the user has indicated whether they wish to show their current location or not.
The MKUserLocation objects passed to the callback are invalid:
2012-03-13 08:20:17.518 MapTest[3325:707] Did update user location: 0.000000,0.000000
2012-03-13 08:20:17.581 MapTest[3325:707] Did update user location: 0.000000,0.000000
Is this the expected behaviour for MKMapKit or a bug?
Update
I'm running this on my iPhone 4, not a simulator. Here's the controller code:
#import "ViewController.h"
@implementation ViewController
@synthesize mapView;
- (void)viewDidLoad
{
[super viewDidLoad];
self.mapView.showsUserLocation = YES;
self.mapView.delegate = self;
}
- (void)viewDidUnload
{
[super viewDidUnload];
// Release any retained subviews of the main view.
}
-(IBAction)trackButtonTapped:(id)sender
{
self.mapView.showsUserLocation = !self.mapView.showsUserLocation;
}
#pragma mark - MKMapKitDelegate
-(void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
NSLog(@"Did update user location: %f,%f", userLocation.coordinate.latitude, userLocation.coordinate.longitude);
}
-(void)mapViewWillStartLoadingMap:(MKMapView *)mapView
{
NSLog(@"Will start loading map");
}
-(void)mapViewDidFinishLoadingMap:(MKMapView *)mapView
{
NSLog(@"Did finish loading map");
}
-(void)mapViewWillStartLocatingUser:(MKMapView *)mapView
{
NSLog(@"Will start locating user");
}
-(void)mapViewDidStopLocatingUser:(MKMapView *)mapView
{
NSLog(@"Did stop locating user");
}
-(void)mapViewDidFailLoadingMap:(MKMapView *)mapView withError:(NSError *)error
{
NSLog(@"Did fail loading map");
}
-(void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error
{
if (error.code == kCLErrorDenied){
NSLog(@"User refused location services");
} else {
NSLog(@"Did fail to locate user with error: %@", error.description);
}
}
@end
回答1:
My opinion is that it's a bug.
How can the map view say user location has been updated when the user hasn't even granted permission?
The workaround I use is to check if userLocation.location
is nil
:
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
{
if (userLocation.location == nil)
return;
//do something with userLocation...
}
回答2:
instead checking for nil userlocation (where 0,0 coordinates can actually be valid) you should use:
if([CLLocationManager authorizationStatus] == kCLAuthorizationStatusAuthorized) {
// do something with the coords
} else {
// the coords are invalid
}
回答3:
With "self.mapView.showsUserLocation = YES;" in viewDidLoad it will start trying to get the user's location straight away. If you take that out it'll wait until the user has pressed a button.
回答4:
Maybe this helps someone. For me the "problem" was that I had set show user's location trough interface builder too. Removing it here and setting it through code made the delegate methods get work as suspected.
来源:https://stackoverflow.com/questions/9680576/is-this-a-bug-with-mkmapkitdelegate-mapviewdidupdateuserlocation