I created an if-then statement to show a purple pin if the title of the pin is "HQ". The green pins show up correctly. Does anyone know why my pin color for the purple pin is still red?
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MyAnnotation class]])
{
static NSString *annotationIdentifier=#"annotationIdentifier";
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [self.mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
if(annotationView)
{
annotationView.annotation = annotation;
}
else
{
annotationView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
if([[annotationView.annotation title] isEqualToString:#"HQ"])
{
//The pin for the HQ should be purple
annotationView.pinColor = MKPinAnnotationColorPurple;
[annotationView setAnimatesDrop:YES];
}
else
{
//All other new pins should be "green" by default
annotationView.pinColor = MKPinAnnotationColorGreen;
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[annotationView setAnimatesDrop:YES];
}
}
return annotationView;
}
return nil;
}
the map reuses annotation view (or offers to do so)
same as a tableView does cell reusing.
now upon init you set the pin color, but on reusing you don't. so one pin is always the same color.
use different reuse identifiers for the different cases!
static NSString *annotationIdentifier= ([annotation.title isEqualToString:#"HQ"]) ? #"HQ" : "OTHER";
Related
I am working on maps and when you tap a annotation it shows the title and description.
Problem is one annotation is very close to the user's current location so i can't see the title of that annotation because its not tapeable. When i try to tap the annotation nothing happens.
- (MKAnnotationView *) mapView:(MKMapView *)mapView
viewForAnnotation:(id <MKAnnotation>) annotation {
if ([annotation isKindOfClass:[MKUserLocation class]]) {
//Don't trample the user location annotation (pulsing blue dot).
return nil;
}
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"pin"];
pinView.animatesDrop = YES;
pinView.canShowCallout = YES;
if (pinView == nil)
pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pin"];
if([[pinView.annotation title] isEqualToString:#"Store"])
{
pinView.pinColor = MKPinAnnotationColorGreen;
}
return pinView;
}
Is there anyway i can bring the annotation front that blue dot that shows current location?
So i moved
pinView.canShowCallout = YES;
in the last before returning the pinView and it worked.
Hi am trying to change the annotation detail view(show in map image) into a custom design like the second image.
How can i change that background image and all?
my current code is
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id)annotation {
mapView.showsUserLocation = YES;
if([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString *identifier = #"myAnnotation";
MKPinAnnotationView * annotationView = (MKPinAnnotationView*)[_MAPVIEW dequeueReusableAnnotationViewWithIdentifier:identifier];
if (!annotationView)
{
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.pinColor = MKPinAnnotationColorPurple;
annotationView.canShowCallout = YES;
}else {
annotationView.annotation = annotation;
}
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[infoButton addTarget:self action:#selector(showDetailView) forControlEvents:UIControlEventTouchUpInside];
annotationView.rightCalloutAccessoryView = infoButton;
UIImageView *imageV=[[UIImageView alloc]initWithImage:[UIImage imageNamed:#"pin.png"]];
annotationView.leftCalloutAccessoryView=imageV;
return annotationView;
}
current annotation detail view design(when i click on pin then i can see the annotation detail view )
but i want something like this design
please help me.
I want to display my custom annotations in the map and my current location as the standard pin in the map view with the blue color.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString *identifier = #"MapPin";
if ([annotation isKindOfClass:[MyAnnotations class]]) {
MyAnnotations *ann= annotation;
MKAnnotationView *annotationView = (MKAnnotationView *) [self.map dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
if (ann.custom){
annotationView.image = [UIImage imageNamed:#"custom.png"];
}else{
//?? annotationView.image = [UIImage imageNamed:#"bluePin.png?"];
}
} else {
annotationView.annotation = annotation;
}
if(ann.custom){
UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[nextButton addTarget:self action:#selector(annotationPicked) forControlEvents:UIControlEventTouchUpInside];
annotationView.rightCalloutAccessoryView=nextButton;
}
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.multipleTouchEnabled = NO;
return annotationView;
}
return nil;
}
If the custom property is to distinguish between your annotations and the map view's user location, that case is already handled by the first if which checks the annotation's class and the custom property would be unnecessary.
The map view's user location annotation is of type MKUserLocation so the code will return nil in that case and the map view will show the standard blue dot (assuming showsUserLocation is YES).
However, if the custom property is to distinguish between two types of your own annotations, then one problem is that it doesn't handled re-used annotation views properly (when annotationView != nil).
When an annotation view is re-used, its image and rightCalloutAccessoryView may not be right for the current annotation so those properties need to be set (or cleared) whether a view is being re-used or not. For example:
if ([annotation isKindOfClass:[MyAnnotations class]]) {
MyAnnotations *ann= annotation;
MKAnnotationView *annotationView = (MKAnnotationView *) [self.map dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
annotationView.enabled = YES;
annotationView.canShowCallout = YES;
annotationView.multipleTouchEnabled = NO;
} else {
annotationView.annotation = annotation;
}
//set view properties that depend on annotation-specific properties
//regardless of whether view is new or re-used...
if (ann.custom)
{
annotationView.image = [UIImage imageNamed:#"custom.png"];
UIButton *nextButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[nextButton addTarget:self action:#selector(annotationPicked) forControlEvents:UIControlEventTouchUpInside];
annotationView.rightCalloutAccessoryView=nextButton;
}
else
{
annotationView.image = [UIImage imageNamed:#"bluePin.png"];
annotationView.rightCalloutAccessoryView = nil;
}
return annotationView;
}
Though if the custom property is just to separate all your annotations from the map view's user location, it's unnecessary in the first place (as long as you check the annotation's class and set showsUserLocation to YES).
may be you put custom code in this event .because when you click on current location annotation this method calls and may be bacause of that code application crashes.
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
}
Thanks.
I have a problem with the custom image on MapKit annotation. Building a sample project where I am performing the same test, it works properly (although the drop effect and the custom image do not work).
But when I use exactly the same function on my map view project, the custom image does not appear. I noticed that the color pin change function MKPinAnnotationColorPurple does not work either. Is it possible that it depends on some project properties?
The code is:
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString *identifier = #"MyLocation";
if ([annotation isKindOfClass:[MyLocation class]]) {
MKPinAnnotationView *annotationView = (MKPinAnnotationView *) [_mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil) {
annotationView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier];
} else {
annotationView.annotation = annotation;
}
annotationView.enabled = YES;
annotationView.animatesDrop= NO;
annotationView.image=[UIImage imageNamed:#"arrest.png" ];//here we use a nice image instead of the default pins
annotationView.canShowCallout = YES;
UIButton *btnDetails = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
//[btnDetails addTarget:self action:#selector(prova) forControlEvents:UIControlEventTouchUpInside];
annotationView.rightCalloutAccessoryView=btnDetails;
return annotationView;
}
return nil;
}
The UIButtonTypeDetailDisclosure does not appear either (in other projects it does).
In map view, i'm showing current user location. On click on the pin its showing "Current Location". I want to change it to "My Current Location". How can I change it.
Also I want to change the current user location pin color in a timer. Some thing like every one second it should change its color between green, purple and red. Possible to do it?
I'm using map kit's show default location and then manipulating the annotation pin color as below:
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation{
static NSString *AnnotationViewID = #"annotationViewID";
SolarAnnotationView* annotationView = (SolarAnnotationView*)[map dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if(annotationView == nil)
{
if([self CLLocationCoordinate2DEquals:mapView.userLocation.location.coordinate withSecondCoordinate:[annotation coordinate]]) //Show current location with green pin
{
annotationView = [[SolarAnnotationView alloc] initWithAnnotation:annotation];
annotationView.delegate = self;
[annotationView setPinColor:MKPinAnnotationColorGreen];
}
else
{
annotationView = [[SolarAnnotationView alloc] initWithAnnotation:annotation];
annotationView.delegate = self;
}
}
return annotationView;
}
- (BOOL) CLLocationCoordinate2DEquals:(const CLLocationCoordinate2D)lhs withSecondCoordinate:(const CLLocationCoordinate2D) rhs{
const CLLocationDegrees DELTA = 0.001;
return fabs(lhs.latitude - rhs.latitude) <= DELTA && fabs(lhs.longitude - rhs.longitude) <= DELTA;
}
If you let the map view show the default annotation view for the user location (blue dot), this is simpler to implement (and you get a nice blue dot with cool animated zooming circle).
If you must show the user location using a pin image instead of a blue dot, then some more work is needed.
First, the simple way using the blue dot:
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation{
if ([annotation isKindOfClass:[MKUserLocation class]])
{
((MKUserLocation *)annotation).title = #"My Current Location";
return nil; //return nil to use default blue dot view
}
//Your existing code for viewForAnnotation here (with some corrections)...
static NSString *AnnotationViewID = #"annotationViewID";
SolarAnnotationView* annotationView = (SolarAnnotationView*)[map dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if(annotationView == nil)
{
{
annotationView = [[[SolarAnnotationView alloc] initWithAnnotation:annotation] autorelease];
//added autorelease above to avoid memory leak
annotationView.delegate = self;
}
}
//update annotation in view in case we are re-using a view
annotationView.annotation = annotation;
return annotationView;
}
If you want to use your custom annotation view for the user location instead, you should put the pin color changing code in the custom view. One way to periodically change the color is using performSelector:withObject:afterDelay:. In the SolarAnnotationView.m, add these two methods:
-(void)startChangingPinColor
{
switch (self.pinColor) {
case MKPinAnnotationColorRed:
self.pinColor = MKPinAnnotationColorGreen;
break;
case MKPinAnnotationColorGreen:
self.pinColor = MKPinAnnotationColorPurple;
break;
default:
self.pinColor = MKPinAnnotationColorRed;
break;
}
[self performSelector:#selector(startChangingPinColor) withObject:nil afterDelay:1.0];
}
-(void)stopChangingPinColor
{
[NSObject cancelPreviousPerformRequestsWithTarget:self];
}
Also add the method headers to the SolarAnnotationView.h file.
Then change the viewForAnnotation method like this:
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation{
static NSString *AnnotationViewID = #"annotationViewID";
SolarAnnotationView* annotationView = (SolarAnnotationView*)[map dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];
if(annotationView == nil)
{
{
annotationView = [[[SolarAnnotationView alloc] initWithAnnotation:annotation] autorelease];
annotationView.delegate = self;
}
}
//Update annotation in view in case we are re-using a view...
annotationView.annotation = annotation;
//Stop pin color changing in case we are re-using a view that has it on
//and this annotation is not user location...
[annotationView stopChangingPinColor];
if([self CLLocationCoordinate2DEquals:mapView.userLocation.location.coordinate withSecondCoordinate:[annotation coordinate]]) //Show current location with green pin
{
[annotationView setPinColor:MKPinAnnotationColorGreen];
annotationView.canShowCallout = YES;
((MKPointAnnotation *)annotation).title = #"My Current Location";
[annotationView startChangingPinColor];
}
return annotationView;
}