How to change MKMapView's user-location blue dot to an image of choice?
Asked Answered
G

5

34

Is it possible to change the blue dot which indicates the user's location in MKMapView to an image? For example a little car or any .png image?

enter image description here

Gem answered 9/6, 2011 at 13:22 Comment(0)
H
56

In the viewForAnnotation: method of MKMapViewDelegate probably you would be having the code like this.

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {

    if (annotation == mapView.userLocation) return nil;
    ...

We return nil if the annotation is userLocation to let the mapView display the blue dot & circle animation. In order to show our custom annotation for userLocation just remove the line return nil; and do your customization there.

- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {

    static NSString* AnnotationIdentifier = @"Annotation";
    MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];

    if (!pinView) {

        MKPinAnnotationView *customPinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];   
        if (annotation == mapView.userLocation){
           customPinView.image = [UIImage imageNamed:@"myCarImage.png"];
        }
        else{
            customPinView.image = [UIImage imageNamed:@"mySomeOtherImage.png"];
        }
        customPinView.animatesDrop = NO;
        customPinView.canShowCallout = YES;
        return customPinView;

    } else {

        pinView.annotation = annotation;
    }

    return pinView;
}
Heptagonal answered 9/6, 2011 at 13:47 Comment(7)
Just on a side note - is there an easy way to maintain the light-blue "accuracy" circle underneath the custom image?Gem
@Nideo, I guess you have to create an annotation with the coordinates of userLocation annotation. Inside the didUpdateToLocation: method you need to update your new annotation as well. But I don'e know whether this will work as you expect. This may fail in the condition if (annotation == mapView.userLocation) because your new annotation is also contains the coordinates of the user location. I am not sure though. Give it a try!Heptagonal
@Simon, this works great at changing the image - but as soon as I move around - the "car" stays at its original point. I.e. the screen follows me but not the annotation. This is the only annotation I will have, so can I rather just return the "car" every time in mapView:viewForAnnotation ?Gem
@Nideo, It should automatically move the annotation. Does the annotation move to the new location when you use the default blue-dot annotation? Just check itHeptagonal
@EmptyStack, I've done a similar thing, and made my annotaiton move when the blue dot does, ie it covers it. Unfortuantely the blue dot animates nicely to the new position whereas my annotation jumps ahead, so you are constantly seeing the blue dot for a little bit each time.Zitazitah
@RodH257, Sorry man. I have no idea about that. Now only I getting to know about this problem. It seems there is a solution here. #3514859Heptagonal
Create a MKAnnotationView not a MKPinAnnotationViewCroatia
L
5

Here is Swift 2.0 version in which you might have multiple pins.

In this code CustomAnnotation is just an MKAnnotation subclass. Basically if the annotation is not the kind of one of your custom classes, then its the user location pin.

func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView?
{
    // This is false if its a user pin
    if(annotation.isKindOfClass(CustomAnnotation) == false)
    {
        let userPin = "userLocation"
        if let dequeuedView = _view.mapView().dequeueReusableAnnotationViewWithIdentifier(userPin)
        {
            return dequeuedView
        } else
        {
            let mkAnnotationView:MKAnnotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: userPin)
            mkAnnotationView.image = UIImage(named: C_GPS.ROUTE_WALK_ICON_NAME)
            let offset:CGPoint = CGPoint(x: 0, y: -mkAnnotationView.image!.size.height / 2)
            mkAnnotationView.centerOffset = offset

            return mkAnnotationView
        }

    }

    let annotation = annotation as? CustomAnnotation
    if(annotation == nil)
    {
        return nil
    }

    let endPointsIdentifier = "endPoint"
    if let dequeuedView = _view.mapView().dequeueReusableAnnotationViewWithIdentifier(endPointsIdentifier)
    {
        dequeuedView.image = annotation!.uiimage
        return dequeuedView
    } else
    {
        let mkAnnotationView:MKAnnotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: endPointsIdentifier)
        mkAnnotationView.image = annotation!.uiimage
        let offset:CGPoint = CGPoint(x: 0, y: -mkAnnotationView.image!.size.height / 2)
        mkAnnotationView.centerOffset = offset

        let gesture = UITapGestureRecognizer(target: self, action: "routeTouched:")
        mkAnnotationView.addGestureRecognizer(gesture)

        return mkAnnotationView
    }
}
Linzer answered 22/9, 2015 at 23:33 Comment(0)
T
1

Ok, here is the Swift version:

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> MKAnnotationView! {

    let identifier = "User"

        var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)

        if annotationView == nil{
            annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
            annotationView.canShowCallout = true

        } else {
            annotationView.annotation = annotation
        }

    annotationView.image = UIImage(named: "image")

    return annotationView

}
Trinia answered 9/9, 2015 at 8:44 Comment(3)
This assumes you only have 1 annotation. Not the greatest solution.Linzer
You need to change MKPinAnnotationView for MKAnnotationView, if not it will always draw a pin on the map.Carolinian
You have to check if annotation is related to user location or some other annotation.Clairvoyant
D
0

is this to change the current location blue dot???

func mapView(mapView: MKMapView!, viewForAnnotation annotation: MKAnnotation!) -> 
MKAnnotationView! {

let identifier = "User"

    var annotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier)

    if annotationView == nil{
        annotationView = MKPinAnnotationView(annotation: annotation, reuseIdentifier: identifier)
        annotationView.canShowCallout = true

    } else {
        annotationView.annotation = annotation
    }

    annotationView.image = UIImage(named: "image")

     return annotationView

}
Disarm answered 29/9, 2015 at 11:56 Comment(0)
T
0

Please try this something like this. its working for me in Xcode 7 and swift 2.

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {

    // want to show a custom image if the annotation is the user's location.
    guard !annotation.isKindOfClass(MKUserLocation) else {
        let annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: "userLocation")
        annotationView.image = UIImage(named: "icon_coordinates_self")
        return annotationView
        //return nil
    }

    // for other annotation except current location 
    let annotationIdentifier = "AnnotationIdentifier"

    var annotationView: MKAnnotationView?
    if let dequeuedAnnotationView = mapView.dequeueReusableAnnotationViewWithIdentifier(annotationIdentifier) {
        annotationView = dequeuedAnnotationView
        annotationView?.annotation = annotation
    }
    else {
        let av = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier)
        av.rightCalloutAccessoryView = UIButton(type: .DetailDisclosure)
        annotationView = av
    }

    if let annotationView = annotationView {
        // Configure your annotation view here
        annotationView.canShowCallout = true
        annotationView.image = UIImage(named: "Annotation_map")
    }

    return annotationView
}
Torgerson answered 16/9, 2016 at 9:57 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.