2

I am displaying a user's location on the map using CLLocationManager's coordinates. Everytime I move or zoom the map, the user location pin (blue pin with sonar effect) keeps disappearing and then re-animating back onto the map. (I am NOT referring to the sonar animation effect. The blue dot literally disappears, then re-animates in).

I am not calling any other methods when the map is scrolled/zoomed. Using breakpoints, only the return nil is called in the map's delegate method:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
    //User's Pin
    if([annotation class] == MKUserLocation.class) {
        return nil;
    }

....rest of my code here, nothing else is called as I am only plotting user at this time...
}
JimmyJammed
  • 9,598
  • 19
  • 79
  • 146

3 Answers3

3

In my original answer, I thought that the goal was to replace the blinking blue dot that you get when you use a MKMapView with showUserLocation = YES and userTrackingMode = MKUserTrackingModeFollow. Hence I showed how to replace it with an image or with a standard pin.

But it turns out that the problem is not that there is a blue dot showing the current location, but rather that the animation of it is getting interrupted and it appears and disappears as the user pans and zooms on the map.

I have seen that behavior if you call removeAnnotations and remove all annotations (including the system generated MKUserLocation annotation). I've also seen that behavior if you turn off showUserLocation and turn it back on.

The OP points out that none of these situations apply, but for future readers, those are a few considerations that might cause this behavior.


Original answer:

The easiest answer is to make sure your controller is the delegate for your MKMapView, and then define a viewForAnnotation that detects a MKUserLocation, and replace the annotation view with whatever you want. For example, if you had a @"user.png" image you wanted to show, it might look like:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
    {
        NSString *annotationIdentifier = @"userlocation";
        MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
        if (annotationView)
        {
            annotationView.annotation = annotation;
        }
        else
        {
            annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
            annotationView.image = [UIImage imageNamed:@"user.png"];
        }

        return annotationView;
    }

    // again, if you had other annotation types, such as MKPointAnnotation,
    // handle them here

    if ([annotation isKindOfClass:[MKPointAnnotation class]])
    {
        ...
    }

    return nil;
}

Or, if you wanted to show a standard pin, you could:

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
    {
        if ([annotation isKindOfClass:[MKUserLocation class]])
        {
            NSString *annotationIdentifier = @"userlocation";
            MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
            if (annotationView)
            {
                annotationView.annotation = annotation;
            }
            else
            {
                annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
            }

            return annotationView;
        }
    }

    // again, if you had other annotation types, such as MKPointAnnotation,
    // handle them here

    if ([annotation isKindOfClass:[MKPointAnnotation class]])
    {
        ...
    }

    return nil;
}
Rob
  • 415,655
  • 72
  • 787
  • 1,044
  • The above assumes you've used the "show user location" feature of `MKMapView`. – Rob May 01 '13 at 04:42
  • Yeah my controller is the delegate, all the other pins display just fine and setting breakpoints shows that things are being called in this method. – JimmyJammed May 01 '13 at 22:46
  • This is what I am currently doing for the user location: if ([annotation isKindOfClass:[MKUserLocation class]]) { return nil; } – JimmyJammed May 01 '13 at 22:47
  • But the user's "blue dot" still disapears and re-animates in every time I scroll/zoom the map. – JimmyJammed May 01 '13 at 22:47
  • Hi Rob, correct I DO want to show the blue dot, but I DON'T want it to disappear and keep "animating in" every time the map is scrolled/zoomed. I am not using removeAnnotations. Literally, NOTHING (except viewForAnnotation) is being called when I scroll/zoom the map. So not sure why the user location keeps disappearing and re-animating back in – JimmyJammed May 01 '13 at 23:13
  • @JamesHickman The only things that I know that cause this would be removing annotations (and accidentally `MKUserLocation` in the process), or setting any of the `MKMapView` properties (such as `showUserLocation`). But you say you're doing absolutely nothing. I guess I can only suggest that you start with a blank app, add the map view, and see if you experience the same behavior. Then slowly add features in until you experience the behavior again. Sorry I don't have better suggestions. Are you also starting location services? Maybe try turning that off and see if the behavior changes. – Rob May 02 '13 at 00:09
  • @JamesHickman Alternatively, if you're willing to upload your entire project somewhere, I'd be willing to take a look, if you want. – Rob May 02 '13 at 00:15
  • I am only setting showUserLocation to yes in the viewDidLoad method of the controller. The only code being called is the downloading of the pin's data (i.e. coordinates and other pertinent info), then the setting of the mapview's delegate. I think the issue isn't the re-animation of the user location, but something else entirely causing the map to "reset". I re-posted the question (as the original post was confusing people apparently) with all the code here: http://stackoverflow.com/questions/16328276/ios-mapkit-annotations-disappear-on-map-scroll-zoom – JimmyJammed May 02 '13 at 16:01
0

Catch the default user location annotation under viewForAnnotation delegate method so it's not plotted. You can use a boolean to toggle it on and off, or create your own custom annotation in tandem with LocationManager. This link should get you on the right track:

User Location Anno

Community
  • 1
  • 1
ninehundreds
  • 1,097
  • 2
  • 21
  • 43
  • I think there is some confusion in the question. Please see updated original post. I am not trying to change the user's "blue dot". I am just wondering why it keeps disappearing and then re-animating in every time the map is scrolled/zoomed. – JimmyJammed May 01 '13 at 23:14
0

If you have used the standard mapciew.showsUserLocation = true; to draw the user's location and it sliding on to the screen instead of pulsating in place, then it is probably because of your viewForAnnotation method. Make sure you are only animating the pins you add and not the user's location which the mapview adds.

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
    if ([annotation isKindOfClass:[MKUserLocation class]])
    {
      return nil;
    }
    //do stuff to the annotations that you added
}
Craig
  • 8,093
  • 8
  • 42
  • 74
  • Yes this is what I am currently doing, yet every time I move/zoom the map, it "reloads" the user location and re-animates it in (so the blue dot disappears, then animated back in and starts pulsing). This gives it a "reloading" implication that I don't want. Suggestions? – JimmyJammed May 01 '13 at 22:46
  • I'm not sure what you mean by "reanimating in". when I turn on and off the tracking in Apple's map the dot appears or disappears in place, it doesn't slide in from anywhere.What else does your code do? Any triggers on map finishing a pan or zoom? How many places in your code turn on and off tracking? You should check if they are being called unexpectedly. – Craig May 01 '13 at 23:33
  • Ok so discovered a new bug that may help solve it. I added a bunch of dummy pins to the map. On initial load, they are all displayed. If I scroll/zoom the map, they all disappear and don't re-appear. The "re-animating in" I am referring to is just the blue dot disappears, then the sonar bubble appears (big), then the blue dot appears and the sonar bubble shrinks down and starts animating like normal. – JimmyJammed May 01 '13 at 23:45
  • It's almost like the entire mapView is being re-allocated...? – JimmyJammed May 01 '13 at 23:47
  • Nothing but the delegate method, viewForAnnotation. I am not calling any other code. Nowhere in my code is removeAnnotations or re-allocation of the mapview. – JimmyJammed May 02 '13 at 15:58