pin drop animation - iphone

The default pin drop animation doesn't work in my app, here is some code I wrote:
- (void)viewDidLoad {
/*
some code...
*/
[theMapView addAnnotation:addAnnotation];
[addAnnotation release];
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
MKPinAnnotationView *annoView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"current"];
annoView.animatesDrop = YES;
annoView.pinColor = MKPinAnnotationColorGreen;
return annoView;
}
Right now the pin just appear in the screen as default red one without any animation, the MKMapViewDelegate protocol has been adopted, anyone can see what's wrong here?

First use:
[yourMap_view setDelegate:self];
in ViewDidLoad
Then call this for the drop animation :
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinView = nil;
if(annotation!= map_view.userLocation)
{
static NSString *defaultPin = #"pinIdentifier";
pinView = (MKPinAnnotationView*)[map_view dequeueReusableAnnotationViewWithIdentifier:defaultPin];
if(pinView == nil)
pinView = [[[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:defaultPin]autorelease];
pinView.pinColor = MKPinAnnotationColorPurple; //Optional
pinView.canShowCallout = YES; // Optional
pinView.animatesDrop = YES;
}
else
{
[map_view.userLocation setTitle:#"You are Here!"];
}
return pinView;
}

Related

Customized User Location Annotation did not follow location update

I implemented MKMapViewDelegate method below and customized user location annotation was displayed. However, the annotation did not move when I walked around with the iPhone. When I removed this delegate method, default the blue dot user location annotation followed me.
Please tell me how to move customized user location annotation:
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString* AnnotationIdentifier = #"Annotation";
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (!pinView)
{
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
pinView.animatesDrop = NO;
pinView.canShowCallout = YES;
}
else
{
pinView.annotation = annotation;
}
pinView.image = [UIImage imageNamed:#"star.png"];
return pinView;
}

Custom Annotation pin interfere with mkmapview's showuserlocation on Iphone

Normally if you have showuserlocation enabled, and going to mapview, there will blue point zoom in dynamically to the user's current location. However, if a custom annotation pin is created for different color purpose then the showuserlocation ability will disappear. The code below newAnnotation is culprit. How do you have both custom pin and also showuserlocation ability not interfered.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([[annotation title] isEqualToString:#"Destination"])
{
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"greenpin"];
newAnnotation.pinColor = MKPinAnnotationColorGreen;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = YES;
return newAnnotation;
}
}
Try this
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
// if it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
if ([[annotation title] isEqualToString:#"Destination"])
{
MKPinAnnotationView *newAnnotation = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"greenpin"];
newAnnotation.pinColor = MKPinAnnotationColorGreen;
newAnnotation.animatesDrop = YES;
newAnnotation.canShowCallout = YES;
return newAnnotation;
}
}

MKMapView not updating user position image

My MKMapView shows my position at startup but then the image never 'follows' me. The location gets updated and the screen does follow me, but the original "User Location" image stays behind.
Here is some code snippets:
-(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 = [self rotate:[UIImage imageNamed:#"myCar.png"] orientation:UIImageOrientationUp];
else customPinView.image = [UIImage imageNamed:#"randomPin.png"];
customPinView.animatesDrop = NO;
customPinView.canShowCallout = YES;
return customPinView;
}
else
{
pinView.annotation = annotation;
}
return pinView;
}
-(void)locationUpdate:(CLLocation *)location
{
CLLocationCoordinate2D loc = [location coordinate];
if(isFollowing)
[myMapView setCenterCoordinate:loc];//Works
}
and in my viewDidLoad I do call: [myMapView setShowsUserLocation:YES]; which does work.
So basically somewhere I neglect updating my position or its most possibly where I draw the new image for my current position.
Can anyone possibly see what I am missing or doing wrong there for it to not follow my location updates?
Thanks.
It's not clear if this is the issue but the viewForAnnotation method doesn't look right.
The annotation image is only being set when an annotation view is created. If a view is re-used, the annotation property is updated but not the image. It's possible that the re-used view is for an annotation of a different type requiring a different image.
The method should look something like this:
-(MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
static NSString* AnnotationIdentifier = #"Annotation";
MKPinAnnotationView *pinView = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if (!pinView)
{
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier] autorelease];
pinView.animatesDrop = NO;
pinView.canShowCallout = YES;
}
else
{
pinView.annotation = annotation;
}
if (annotation == mapView.userLocation)
pinView.image = [self rotate:[UIImage imageNamed:#"myCar.png"] orientation:UIImageOrientationUp];
else
pinView.image = [UIImage imageNamed:#"randomPin.png"];
return pinView;
}

how can i place two color pins ? 1 in red and 1 in green?

I am using this sample app to make route
http://blog.kadirpekel.com/2010/05/30/drawing_routes_onto_mkmapview_using_unofficial_google_maps_directions_api/
It will call the routing api and parse the result.
Then a new layer is added above the map with the route between A and B.
My problem is how can i place two color pins ? Right now Its showing 2 red color pins. But I need 1 red and 1 green.
I am trying to work with this delegate, but its not helping me
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
- (MKAnnotationView *)mapView:(MKMapView *)mapView
viewForAnnotation:(id <MKAnnotation>)annotation {
if(annotation == yourFirstAnnotation)
{
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:yourFirstAnnotation reuseIdentifier:[annotation title]];
annView.pinColor = MKPinAnnotationColorRed;
annView.animatesDrop=NO;
annView.canShowCallout = YES;
return [annView autorelease];
}
else
if(annotation == yourSecondAnnotation)
{
MKPinAnnotationView *annView=[[MKPinAnnotationView alloc] initWithAnnotation:yourSecondAnnotation reuseIdentifier:[annotation title]];
annView.pinColor = MKPinAnnotationColorGreen;
annView.animatesDrop=NO;
annView.canShowCallout = YES;
return [annView autorelease];
}
}
I think if it doesn't work make use of isEqual: instead of ==.

Jumping from a custom callout to another one in MKMap

I've been following this tutorial to show custom annotation callout bubbles.
It works perfectly if you have only one annotation with a custom annotationview.
However, I need to have more on my map, and I have troubles switching from a custom annotationview to another one. If I click on another pin when having selected already one and would like to make appear the new custom annotationview, it doesn't work. I have first to click somewhere else random on the mapview. I guess I have something to work on in DidDeselect Method, but I'm not sure...
How would you solve such a problem?
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
if (self.calloutAnnotation && [view.annotation isKindOfClass:[MyHomeAnnotation class]]) {
[self.mapView removeAnnotation: self.calloutAnnotation];
}
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
if ([view.annotation isKindOfClass:[MyHomeAnnotation class]]) {
if (self.calloutAnnotation == nil) {
self.calloutAnnotation = [[CalloutMapAnnotation alloc] initWithLatitude:view.annotation.coordinate.latitude
andLongitude:view.annotation.coordinate.longitude];
} else {
self.calloutAnnotation.latitude = view.annotation.coordinate.latitude;
self.calloutAnnotation.longitude = view.annotation.coordinate.longitude;
}
[self.mapView addAnnotation:self.calloutAnnotation];
self.selectedAnnotationView = view;
}
}
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if (annotation == self.calloutAnnotation) {
CalloutMapAnnotationView *calloutMapAnnotationView = (CalloutMapAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:#"CalloutAnnotation"];
if (!calloutMapAnnotationView) {
calloutMapAnnotationView = [[[CalloutMapAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"CalloutAnnotation"] autorelease];
calloutMapAnnotationView.contentHeight = 78.0f;
UIImage *asynchronyLogo = [UIImage imageNamed:#"cykelrød1.png"];
UIImageView *asynchronyLogoView = [[[UIImageView alloc] initWithImage:asynchronyLogo] autorelease];
asynchronyLogoView.frame = CGRectMake(5, 2, asynchronyLogoView.frame.size.width, asynchronyLogoView.frame.size.height);
[calloutMapAnnotationView.contentView addSubview:asynchronyLogoView];
}
calloutMapAnnotationView.parentAnnotationView = self.selectedAnnotationView;
calloutMapAnnotationView.mapView = self.mapView;
return calloutMapAnnotationView;
} else if ([annotation isKindOfClass:[MyHomeAnnotation class]]) {
MKPinAnnotationView *annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"CustomAnnotation"] autorelease];
annotationView.canShowCallout = NO;
annotationView.pinColor = MKPinAnnotationColorGreen;
return annotationView;
}else if ([annotation isKindOfClass:[MyMapAnnotation class]]) {
MKPinAnnotationView *annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation
reuseIdentifier:#"NormalAnnotation"] autorelease];
annotationView.canShowCallout = YES;
annotationView.pinColor = MKPinAnnotationColorPurple;
return annotationView;
}
return nil;
}
Here are my solution, I use latitude and longitude to distinguish which callout should be remove from mapview. Hope this will be help.
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
NSLog(#"didSelectAnnotationView:%f", view.annotation.coordinate.latitude);
if (self.calloutAnnotation == nil) {
CalloutMapAnnotation *tempCallout = [[CalloutMapAnnotation alloc]
initWithLatitude:view.annotation.coordinate.latitude
andLongitude:view.annotation.coordinate.longitude];
self.calloutAnnotation = tempCallout;
[tempCallout release];
} else {
//remove callout when callout already exist
[self.myMapView removeAnnotation: self.calloutAnnotation];
self.selectedAnnotationView = nil;
//reposition
self.calloutAnnotation.latitude = view.annotation.coordinate.latitude;
self.calloutAnnotation.longitude = view.annotation.coordinate.longitude;
}
[self.myMapView addAnnotation:self.calloutAnnotation];
self.selectedAnnotationView = view;
}
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
NSLog(#"didDeselectAnnotationView:%f", view.annotation.coordinate.latitude);
//use the latitude and longitude to avoid remove twice
if (self.calloutAnnotation &&
self.selectedAnnotationView.annotation.coordinate.latitude == view.annotation.coordinate.latitude &&
self.selectedAnnotationView.annotation.coordinate.longitude == view.annotation.coordinate.longitude
) {
[self.myMapView removeAnnotation: self.calloutAnnotation];
self.selectedAnnotationView = nil;
self.calloutAnnotation.isAddtoMap = NO;
}
}