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

jszumski
  • 7,430
  • 11
  • 40
  • 53
Pangolin
  • 7,284
  • 8
  • 53
  • 67

5 Answers5

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;
}
DevC
  • 6,982
  • 9
  • 45
  • 80
EmptyStack
  • 51,274
  • 23
  • 147
  • 178
  • 1
    Just on a side note - is there an easy way to maintain the light-blue "accuracy" circle underneath the custom image? – Pangolin Jun 09 '11 at 15:31
  • @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! – EmptyStack Jun 10 '11 at 04:28
  • 1
    @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` ? – Pangolin Jun 16 '11 at 06:46
  • @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 it – EmptyStack Jun 16 '11 at 07:06
  • @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. – RodH257 Jun 22 '11 at 07:41
  • @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. http://stackoverflow.com/questions/3514359/avoid-flicker-when-moving-annotations-in-a-mkmapview-on-iphone – EmptyStack Jun 22 '11 at 08:24
  • 2
    Create a MKAnnotationView not a MKPinAnnotationView – Sjoerd Perfors Sep 05 '16 at 07:18
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
    }
}
Aggressor
  • 13,323
  • 24
  • 103
  • 182
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

}
mechdon
  • 517
  • 1
  • 10
  • 23
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

}
Muhammad Usman
  • 1,366
  • 5
  • 18
  • 33
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
}
Museer Ahamad Ansari
  • 5,414
  • 3
  • 39
  • 45