Custom Annotation View for Userlocation Not Moving the Mapview

Custom Annotation view for userlocation not moving the mapview

Yes, you can have a custom view for the user's location.

Unfortunately, it's harder to implement than it should be because even though the documentation for the viewForAnnotation delegate method claims that you can just supply your own view if the annotation class is MKUserLocation, the custom view does not then continue to move with the user's location. In fact, when a custom view is returned for MKUserLocation, the map view stops updating the user location entirely (the map view's didUpdateUserLocation delegate method no longer fires). I believe this is a bug.

A workaround is to use CLLocationManager and a custom annotation...



Make sure showsUserLocation is NO or unchecked on the map view.

Declare properties for a CLLocationManager and a custom annotation using a custom class that implements the MKAnnotation protocol (or you could just use the generic MKPointAnnotation class).

In viewDidLoad or some other appropriate place, create the CLLocationManager, set its delegate and call startUpdatingLocation.

In the location manager's didUpdateToLocation delegate method (not the map view's didUpdateUserLocation delegate method), create or update your custom annotation:

-(void)locationManager:(CLLocationManager *)manager didUpdateToLocation:(CLLocation *)newLocation fromLocation:(CLLocation *)oldLocation
{
if (myUserLocAnnot == nil)
{
self.myUserLocAnnot = [[[MyUserLocClass alloc] init] autorelease];
//remove the autorelease if using ARC
myUserLocAnnot.title = @"You are here";
myUserLocAnnot.coordinate = newLocation.coordinate;
[mapView addAnnotation:myUserLocAnnot];
}
else
{
myUserLocAnnot.coordinate = newLocation.coordinate;
}
}

Finally, in the map view's viewForAnnotation delegate method, you would return a custom annotation view if the annotation is your custom user location annotation.

MKMapView iOS custom user location Annotation not showing/updating position

Yep all the above code works! Finally got it working. So Steps for custom user loc that also updates with your movements are above.

(MapView) Userlocation image changed help to restore

In your viewFor annotation function add this row in the beginning:

if annotation is MKUserLocation {
return nil
}

Because you don´t want to do anything if it´s the MKUserLocation.

didUpdateUserLocation not called when view for userLocation is custom

Instead of relying on the map view's location updates, start a CLLocationManager, set its delegate and wait for -locationManager:didUpdateToLocation:fromLocation: (in iOS 5 and lower) or -locationManager:didUpdateLocations: (iOS 6). You will get much more reliable and plentiful information than using the map view's delegate methods. You probably know the way to do this, but here it is:

#import 

- (void)viewWillAppear:(BOOL)animated
{
self.locationManager = [[CLLocationManager alloc] init];
self.locationManager.delegate = self;
[self.locationManager setDesiredAccuracy:kCLLocationAccuracyBest];
[self.locationManager startUpdatingLocation];
}

// Deprecated in iOS 6
- (void)locationManager:(CLLocationManager *)manager
didUpdateToLocation:(CLLocation *)newLocation
fromLocation:(CLLocation *)oldLocation
{

// Check the age of the newLocation isn't too long ago using newLocation.timestamp

// Set the map dot using newLocation.coordinate

// Set an MKCircle to represent accuracy using newLocation.horizontalAccuracy
}

I had a look at the delegate calls that come in to the mapView's delegate, and returning anything other than nil stops calls to -mapView:didUpdateUserLocation:, like you said. Here are the calls in the order they arrive:

 - (void)mapViewWillStartLocatingUser:(MKMapView *)mapView
- (void)mapView:(MKMapView *)mapView didUpdateUserLocation:(MKUserLocation *)userLocation
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id < MKAnnotation >)annotation
- (void)mapViewWillStartLoadingMap:(MKMapView *)mapView
- (void)mapView:(MKMapView *)mapView didFailToLocateUserWithError:(NSError *)error

Presumably the MKUserLocation object, not the MKMapView is the object responsible for calling the delegate with update calls. If you check the status of showsUserLocation and mapView.userLocation, they both look fine:

NSLog(@"%d %@", mapView.showsUserLocation, mapView.userLocation);

returns 1 and a non-nil object (1 ). Maybe the mapView queries its userLocation object to get the current location, then sends it to the delegate. If that object has gone, it won't work.

It's a bit strange, but like I said, you'll get better updates from a CLLocationManager's updates.



Related Topics



Leave a reply



Submit