MKMapView: Instead of Annotation Pin, a custom view
When you want to use your own image for an annotation view, you should create an MKAnnotationView
instead of an MKPinAnnotationView
.
MKPinAnnotationView
is a subclass of MKAnnotationView
so it has an image
property but it generally overrides that and draws a pin image (that's what it's for).
So change the code to:
-(MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation { MKAnnotationView *pinView = nil; if(annotation != mapView.userLocation) { static NSString *defaultPinID = @"com.invasivecode.pin"; pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID]; if ( pinView == nil ) pinView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID]; //pinView.pinColor = MKPinAnnotationColorGreen; pinView.canShowCallout = YES; //pinView.animatesDrop = YES; pinView.image = [UIImage imageNamed:@"pinks.jpg"]; //as suggested by Squatch } else { [mapView.userLocation setTitle:@"I am here"]; } return pinView;}
Notice that animatesDrop
is also commented out since that property only exists in MKPinAnnotationView
.
If you still want your image annotations to drop, you'll have to do the animation yourself. You can search Stack Overflow for "animatesdrop mkannotationview" and you'll find several answers. Here are the first two:
Here's an answer on Swift 3. It dequeues annotation view if possible or creates a new one if not:
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { // Don't want to show a custom image if the annotation is the user's location. guard !(annotation is MKUserLocation) else { return nil } // Better to make this class property let annotationIdentifier = "AnnotationIdentifier" var annotationView: MKAnnotationView? if let dequeuedAnnotationView = mapView.dequeueReusableAnnotationView(withIdentifier: annotationIdentifier) { annotationView = dequeuedAnnotationView annotationView?.annotation = annotation } else { annotationView = MKAnnotationView(annotation: annotation, reuseIdentifier: annotationIdentifier) annotationView?.rightCalloutAccessoryView = UIButton(type: .detailDisclosure) } if let annotationView = annotationView { // Configure your annotation view here annotationView.canShowCallout = true annotationView.image = UIImage(named: "yourImage") } return annotationView}
Swift 2.2:
func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? { // Don't want to show a custom image if the annotation is the user's location. guard !annotation.isKindOfClass(MKUserLocation) else { return nil } // Better to make this class property 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: "yourImage") } return annotationView}
I agree with with answer of the Anna and i like to show how will look that in swift3.This answer it's with many other options.Like a resize the image, get a list of images from array and ect.
func mapView(_ mapView: MKMapView, viewFor annotation: MKAnnotation) -> MKAnnotationView? { if let annotation = annotation as? PetrolStation { let identifier = "pinAnnotation" var view: MKAnnotationView if let dequeuedView = mapView.dequeueReusableAnnotationView(withIdentifier: identifier) as? MKPinAnnotationView { // 2 dequeuedView.annotation = annotation view = dequeuedView } else { // 3 view = MKAnnotationView(annotation: annotation, reuseIdentifier: identifier) view.canShowCallout = true //here We put a coordinates where we like to show bubble with text information up on the pin image view.calloutOffset = CGPoint(x: -7, y: 7) //Here this is a array of images let pinImage = PetrolItem[activePlace].imgPetrol?[activePlace] //Here we set the resize of the image let size = CGSize(width: 30, height: 30) UIGraphicsBeginImageContext(size) pinImage?.draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height)) let resizeImage = UIGraphicsGetImageFromCurrentImageContext() UIGraphicsEndImageContext() view.image = resizeImage //Here we like to put into bubble window a singe for detail Informations view.rightCalloutAccessoryView = UIButton(type: .detailDisclosure) as UIView //Here we make change of standard pin image with our image view.image = resizeImage } return view } return nil }