I have multiple Annotation in a MapView, listed in 3 different arrays.
I've used the - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation method to change te Callout of the annotation.
The weird thing is that my UserLocation is changing into an Customised Annotation.
Why is that, and what could be the problem?
How I listed my Annotations:
myAnn = [[Annotations alloc]init];
location.latitude = 52.338847;
location.longitude = 4.937482;
myAnn.coordinate = location;
myAnn.title = #"Afvalpunt";
myAnn.subtitle = #"Rozenburglaan 1";
[category3 addObject:myAnn];
[self.locationArrays addObject:category3];
self.currentAnnotation = 0;
[self.myMapView addAnnotations:[self.locationArrays objectAtIndex:0]];
How my Method is set up:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:#"MapAn"];
if (!annotationView) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"MapAn"];
annotationView.canShowCallout = YES;
//Blauw Navigatie Auto...
UIImageView *carView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"Driving"]];
UIButton *blueView = [[UIButton alloc] initWithFrame:CGRectMake(0, 0, 44, 44+30)];
blueView.backgroundColor = [UIColor colorWithRed:0 green:0.5 blue:1 alpha:1];
carView.frame = CGRectMake(11, 14, carView.image.size.width, carView.image.size.height);
[blueView addTarget:self action:#selector(carClicked) forControlEvents:UIControlEventTouchUpInside];
[blueView addSubview:carView];
annotationView.leftCalloutAccessoryView = blueView;
}
return annotationView;
}
Try this code.
- (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;
}
Hope this code is useful for you.
Try this code
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]] || annotation==mapView.userLocation)
{
return nil;//Here you can also customise your pin if you dont want pin then just return nil.
}
else
{
//your code
}
}
Related
I have changed my MapView pin image but I am getting this problem that some of the point wont change the pin image and some of them change. Where would be the problem? I have added an example.
My Code:
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinAnnotation = nil;
MKAnnotationView *pinView = nil;
if(annotation != locationMap.userLocation)
{
static NSString *defaultPinID = #"myPin";
pinAnnotation = (MKPinAnnotationView *)[locationMap dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinAnnotation == nil )
pinAnnotation = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
pinAnnotation.canShowCallout = YES;
pinAnnotation.animatesDrop = YES;
pinAnnotation.enabled = YES;
//pinAnnotation.image = [UIImage imageNamed:#"pin.png"];
pinView.image = [UIImage imageNamed:#"pin.png"];
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinAnnotation.rightCalloutAccessoryView = infoButton;
}
return pinAnnotation;
return pinView;
}
Use a regular MKAnnotationView, not the MKPinAnnotationView subclass. Even though you can set the image it isn't guaranteed to stick because it can and will set the pin image back again.
I have a mapView with a strange behavior: When I open it, everything works fine. The user (blue with circles) is going to be located and the 3 pins are in position. But (I don't know why) after a some time, the blue point turns into a pin - but only when I have slow connection speed.
Here's what I got:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"pinView"];
if (!pinView && ![annotation isKindOfClass:[MKUserLocation class]])
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pinView"];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = rightButton;
if (annotation == self.locationZH1)
{
[pinView setTag:1];
}
else if (annotation == self.locationZH2)
{
[pinView setTag:2];
}
else if (annotation == self.locationZH3)
{
[pinView setTag:3];
}
else if (annotation == self.locationLU1)
{
[pinView setTag:4];
}
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
Be sure to avoid providing an annotation view for the built in user location marker.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
//check annotation is not user location
if([annotation isEqual:[mapView userLocation]])
{
//bail
return nil;
}
static NSString *annotationViewReuseIdentifer = #"map_view_annotation";
//dequeue annotation view
MKPinAnnotationView *annotationView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:annotationViewReuseIdentifer];
if(!annotationView)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationViewReuseIdentifer];
}
//set annotation view properties
[annotationView setAnnotation:annotation];
return annotationView;
}
By checking for the user location annotation earlier, you can provide an early out for returning nil rather than allocating a new MKPinAnnotationView and returning that instead.
The documentation for - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation states:
If the object in the annotation parameter is an instance of the
MKUserLocation class, you can provide a custom view to denote the
user’s location. To display the user’s location using the default
system view, return nil.
Swift 3 Solution :
if annotation is MKUserLocation{
return nil
}
You need to return nil when annotation == mapView.userLocation to show the blue dot for user location and the circle around it
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"pinView"];
if (!pinView && ![annotation isKindOfClass:[MKUserLocation class]])
{
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pinView"];
pinView.pinColor = MKPinAnnotationColorRed;
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = rightButton;
if (annotation == self.locationZH1)
{
[pinView setTag:1];
}
else if (annotation == self.locationZH2)
{
[pinView setTag:2];
}
else if (annotation == self.locationZH3)
{
[pinView setTag:3];
}
else if (annotation == self.locationLU1)
{
[pinView setTag:4];
}
return pinView;
}
else
{
pinView.annotation = annotation;
return Nil;
}
}
On initial load, the annotations show just fine. But if I scroll the map, they all disappear and the code is only called for the user location, not the other annotations in the viewForAnnotation delegate method.
Plot Pins
-(void)viewDidLoad{
...Download Coordinates and Data from Web here...
[self.mapView addAnnotation:pin];
}
Delegate Method
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
//Player's Pin
if([annotation class] == MKUserLocation.class) {
return nil;
}
//Cluster Pin
if([annotation isKindOfClass:[REVClusterPin class]]){
REVClusterPin *pin = (REVClusterPin *)annotation;
if( [pin nodeCount] > 0 ){
pin.title = #"___";
MKAnnotationView *annotationView = (REVClusterAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:#"cluster"];
if( !annotationView ){
annotationView = (REVClusterAnnotationView*)
[[REVClusterAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"cluster"];
}
annotationView.image = [UIImage imageNamed:#"cluster.png"];
[(REVClusterAnnotationView*)annotationView setClusterText:
[NSString stringWithFormat:#"%i",[pin nodeCount]]];
annotationView.canShowCallout = NO;
return annotationView;
}
}
//Player Pin
if([annotation isKindOfClass:[ZEPointAnnotation class]]){
ZEPointAnnotation *pin = (ZEPointAnnotation *)annotation;
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:#"pin"];
if(!annotationView){
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pin"];
}
annotationView.canShowCallout = YES;
annotationView.draggable = NO;
...Create Pin Data Here...
return annotationView;
}
return nil;
}
remove animations. that will solve your problem
I was wonderring if there is a way to change those red pins that are used as markers. And if there is a way, how to do it?
you can use 3 types of color pins in mapView are bellow..
MKPinAnnotationColorGreen;
MKPinAnnotationColorPurple
MKPinAnnotationColorRed
and if you want to add customview or image then you can add with programatically
also you can change pin in delegate method of MKMapView like bellow..
- (MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
if (annotation == _mapView.userLocation)
{
// pinView.pinColor = MKPinAnnotationColorRed;
// return pinView;
return nil;
}
pinView.pinColor = MKPinAnnotationColorGreen; // you can use MKPinAnnotationColorPurple, MKPinAnnotationColorRed;
pinView.canShowCallout = YES;
pinView.animatesDrop = NO;
return pinView;
}
and for custom image or pin, use bellow code..
- (MKAnnotationView *)mapView:(MKMapView *)_mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString *AnnotationViewID = #"annotationViewID";
MKAnnotationView *annotationView = (MKAnnotationView *)[_mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if (annotationView == nil)
{
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];
}
annotationView.image = [UIImage imageNamed:#"yourImageName"];//add any image which you want to show on map instead of red pins
annotationView.annotation = annotation;
return annotationView;
}
I have an annotation showing in mapkit with a custom image, showing fine,
but the annotation shows after taping the pin,
how can I have the annotation showing by default?, when I start the view? whit out tapping the pin.
- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MKUserLocation class]])
return nil;
NSString *annotationIdentifier = #"PinViewAnnotation";
MKPinAnnotationView *pinView = (MKPinAnnotationView *) [mapView
dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
if (!pinView)
{
pinView = [[[MKPinAnnotationView alloc]
initWithAnnotation:annotation
reuseIdentifier:annotationIdentifier] autorelease];
[pinView setPinColor:MKPinAnnotationColorGreen];
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
UIImageView *houseIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"tijereta.png"]];
pinView.leftCalloutAccessoryView = houseIconView;
[houseIconView release];
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
thanks
you can use this
[mapView selectAnnotation:pinView animated:YES]; //here pinView is your annotation and mapview is your map
hope that helped