how to make custom pin like friends map of 4sq app - iphone

How to make custom pin like foursquare friends map instead of pin on map?
image is here, http://www.socialmedianews.com.au/wp-content/uploads/2010/07/foursquare-friends-map.png

- (MKAnnotationView *)mapView:(MKMapView *)mv viewForAnnotation:(id <MKAnnotation>)annotation {
MKAnnotationView *pinView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:#"pinView"];
if (!pinView) {
pinView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"pinView"] autorelease];
pinView.image = [UIImage imageNamed:#"SPOON4.png"];
pinView.frame = CGRectMake(-30, 0, 70, 67.5);
//pinView.animatesDrop = YES; can't animate with custom pin images
pinView.canShowCallout = YES;
UIButton *rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinView.rightCalloutAccessoryView = rightButton;
} else {
pinView.annotation = annotation;
}
if (annotation == mapView.userLocation){
return nil; //default to blue dot
}
return pinView;
}

You need to use a custom MKAnnotationView.
You can use the MKAnnotationView class
as is or subclass it to provide custom
behavior as needed. The image property
of the class lets you set the
appearance of the annotation view
without subclassing directly. You
might also create custom subclasses as
a convenience and use them to put the
annotation view in a known state. For
example, the MKPinAnnotationView
subclass initializes the contents of
the annotation view to a pin image.

You want to replace the custom pin with a framed portrait. You can draw the frame with Quartz, or add the frame as a second transparent image. I would do the second adding the following to MKAnnotationView:
- (id)initWithAnnotation:(id <MKAnnotation>)annotation
reuseIdentifier:(NSString *)reuseIdentifier {
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
if (self != nil) {
self.opaque = NO;
self.frame = CGRectMake(0,0, self.portraitImage.size.width, self.portraitImage.size.height);
}
return self;
}
- (void)drawRect:(CGRect)rect {
[self.frameImage drawInRect:CGRectMake(0, 0, frameImage.width, frameImage.height)];
[self.portraitImage drawInRect:CGRectMake(0, 0, portraitImage.width, portraitImage.height)];
}

Related

How to show Image over Map not as Pin but as seperate image? [duplicate]

This question already has answers here:
MKMapView: Instead of Annotation Pin, a custom view
(3 answers)
Closed 9 years ago.
I want to show two flags on Map but these are not pins. I search a lot for this but could not find solutions but to add as pin.
please help
You are looking for Map Overlay MKOverlayView.
Check these tutorials:
Overlay View
Image Overlay
Creating overlay
Creating a MKOverlayView
Create a subclass of MKOverlayView like:
.h
#import
#import
#interface MapOverlayView : MKOverlayView
{
}
#end
.m
#import "MapOverlayView.h"
#implementation MapOverlayView
- (void)drawMapRect:(MKMapRect)mapRect zoomScale:(MKZoomScale)zoomScale inContext:(CGContextRef)ctx
{
UIImage *image = [UIImage imageNamed:#"yourImage.png"];
CGImageRef imageReference = image.CGImage;
MKMapRect theMapRect = [self.overlay boundingMapRect];
CGRect theRect = [self rectForMapRect:theMapRect];
CGContextDrawImage(ctx, theRect, imageReference);
}
#end
Adding Overlay
Implement the viewForOverlay: ,inside that create the overlay and add to map.
- (MKOverlayView *)mapView:(MKMapView *)mapView viewForOverlay:(id <MKOverlay>)overlay
{
MapOverlay *mapOverlay = (MapOverlay *)overlay;
MapOverlayView *mapOverlayView = [[[MapOverlayView alloc] initWithOverlay:mapOverlay] autorelease];
return mapOverlayView;
}
you can do it with MKAnnotationView with image property like bellow in viewForAnnotation: method..
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString *identifier = #"Current";
MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (annotationView == nil)
{
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier] autorelease];
}
if (annotation == mapView.userLocation)
return nil;
annotationView.image = [UIImage imageNamed:#"yourImageName.png"];
annotationView.annotation = annotation;
annotationView.canShowCallout = YES;
return annotationView;
}
try this one
annotation = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"try"];
annotation.canShowCallout = YES;
annotation.image = [UIImage imageNamed:#"image.png"];
return annotation;
and do not use annotation.animatesDrop property.
If you are talkin about MKMapView:
To show an image instead of Pin annotation , you need to override MKMapView's method
- (MKAnnotationView *)viewForAnnotation:(id < MKAnnotation >)annotation
Like this:
- (MKAnnotationView *)viewForAnnotation:(id < MKAnnotation >)annotation{
static NSString* annotationIdentifier = #"Identifier";
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:annotationIdentifier];
if(annotationView)
return annotationView;
else
{
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:annotationIdentifier];
annotationView.canShowCallout = YES;
// here you need to give the image you want instead of pin
annotationView.image = [UIImage imageNamed:[NSString stringWithFormat:#"balloon.png"]];
return annotationView;
}
return nil;
}

MKAnnotationView doesn't show custom pin

I'm implementing a custom pin for a map, the image is in te project's folder but didn't show.
Perhaps (and very likely) I'm doing something wrong.
The map displays and shows the pins (default red pins) but not the custom image nor the UIButtonTypeDetailDisclosure
This is the code I'm using:
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id<MKAnnotation>)annotation
{
// in case it's the user location, we already have an annotation, so just return nil
if ([annotation isKindOfClass:[MKUserLocation class]])
{
return nil;
}
static NSString *TheAnnotationIdentifier = #"theAnnotationIdentifier";
MKAnnotationView *shoppeAnnotationView =
[self.mapView dequeueReusableAnnotationViewWithIdentifier:TheAnnotationIdentifier];
if (shoppeAnnotationView == nil)
{
MKAnnotationView *annotationView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:TheAnnotationIdentifier];
annotationView.canShowCallout = YES;
annotationView.image = [UIImage imageNamed:#"pin.png"];
annotationView.rightCalloutAccessoryView = [ UIButton buttonWithType:UIButtonTypeDetailDisclosure ];
annotationView.opaque = NO;
return annotationView;
}
return nil;
}
Any hints?
Thank you!

iOS- Get button on MKAnnotationView to delete pin

I have created a MKAnnotationView and do add a UIButton on it. Now I would like that button to remove the pin it is in.
This is how I add the button:
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinAnnotation = nil;
if(annotation != myMapView.userLocation)
{
NSString *defaultPinID = [[NSString alloc] initWithFormat:#"pin%d",pinCount];
pinAnnotation = (MKPinAnnotationView *)[myMapView dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinAnnotation == nil )
pinAnnotation = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
pinAnnotation.canShowCallout = YES;
//// ADDING MY BUTTON
UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinAnnotation.rightCalloutAccessoryView = deleteButton;
//// ADDING IT'S ACTION
[deleteButton addTarget:self action:#selector(deletePin) forControlEvents:UIControlEventTouchUpInside];
}
pinCount++;
return pinAnnotation;
}
As you can see there, I set the action to call this method:
-(void)deletePin
{
//What to put here...?
}
How can I make that action delete it's button's pin?
I figured maybe sending the id thru or something, but am not sure how.
With annotation callout accessory views, do not use your own target/action method.
Instead, use the map view's calloutAccessoryControlTapped delegate method which will make this job much easier.
Remove the addTarget line and your custom method. Then implement the delegate method instead:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view
calloutAccessoryControlTapped:(UIControl *)control
{
[mapView removeAnnotation:view.annotation];
}
Also, unrelated, but the way you are setting the re-use identifier is wrong and defeats re-usability by assigning a different id to every annotation. The following is recommended:
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinAnnotationView = nil;
if (annotation != myMapView.userLocation)
{
NSString *reuseId = #"StandardPin";
pinAnnotationView = (MKPinAnnotationView *)[myMapView dequeueReusableAnnotationViewWithIdentifier:reuseId];
if ( pinAnnotationView == nil )
{
pinAnnotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:reuseId] autorelease];
pinAnnotationView.canShowCallout = YES;
UIButton *deleteButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinAnnotationView.rightCalloutAccessoryView = deleteButton;
}
else
//update annotation property if view is being re-used...
pinAnnotationView.annotation = annotation;
}
return pinAnnotationView;
}
Get the sender in your callback
[deleteButton addTarget:self action:#selector(deletePin:) forControlEvents:UIControlEventTouchUpInside];
-(void)deletePin:(id)sender
{
//What to put here...?
}
Then get the MKAnnotation associated with the MKPinAnnotationView, remove it from the MKMapView's annotations and redraw ([mapView setNeedsDisplay])

Change pin design

Is it possible to change the MKAnnotation pin to a png of my own design?
override this and be a delegate of MKMapViewDelegate to implement override the method.
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation;
Create an annotation,
MKAnnotationView *annotationView = (MKAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationViewID];// get a dequeued view for the annotation like a tableview
if (annotationView == nil)
{
annotationView = [[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationViewID] autorelease];
}
annotationView.annotation = annotation;
annotationView.canShowCallout = YES; // show the grey popup with location etc
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
///[rightButton addTarget:self action:#selector(showDetails:) forControlEvents:UIControlEventTouchUpInside];
annotationView.rightCalloutAccessoryView = rightButton;
annoationView.image = [UIImage imageNamed:#"random.png"];
Custom image done
Yes, in the viewForAnnotation delegate callback you can provide whatever view you like.
For custom annotation image, set the image property, as such.
UIImage *annImage = [UIImage imageNamed:#"AnnotationIcon.png"];
annView.image = annImage;
Do note that the MKPinAnnotationView animateDrop property will not work on custom images. There's a way to duplicate that animation though. See How do I animate MKAnnotationView drop?

setting up Image in MKAnnotationPinView

I have the following code inside the delegate:
- (MKAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)anAnnotation
{
MKPinAnnotationView *pin = (MKPinAnnotationView *) [map dequeueReusableAnnotationViewWithIdentifier: #"RoutePin"];
if (pin == nil)
{
if ([anAnnotation isKindOfClass:[RouteMapAnnotation class]])
{
RouteMapAnnotation *theAnnotation = (RouteMapAnnotation *)anAnnotation;
if (theAnnotation.identifier == #"routePin")
{
//NSLog(#"TESTING PART III");
MKPinAnnotationView *startAnnotationPin = [[MKPinAnnotationView alloc] initWithAnnotation:anAnnotation reuseIdentifier:#"RoutePin"];
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
startAnnotationPin.canShowCallout = YES;
startAnnotationPin.animatesDrop = YES;
startAnnotationPin.rightCalloutAccessoryView = rightButton;
startAnnotationPin.pinColor = MKPinAnnotationColorRed;
return startAnnotationPin;
}
else if (theAnnotation.identifier == #"finishPin")
{
NSLog(#"CREATING FINISH FLAG PRIOR");
MKPinAnnotationView *finishAnnotationPin = [[MKPinAnnotationView alloc] initWithAnnotation:anAnnotation reuseIdentifier:#"FinishPin"];
finishAnnotationPin.canShowCallout = NO;
finishAnnotationPin.animatesDrop = YES;
//finishAnnotationPin.image = [UIImage imageWithData:[NSData dataWithContentsOfURL:[NSURL URLWithString:#"http://cdn4.iconfinder.com/data/icons/formula1/f1_png/128/checkered_flag.png"]]];
finishAnnotationPin.image = [UIImage imageNamed:#"flag_finish"];
return finishAnnotationPin;
}
}
}
return nil;
}
However it's not showing the image for the pin on the map. What am I missing??
You should use MKAnnotationView instead of MKPinAnnotationView.
pin annotation is for pins.
Also note that MKPinAnnotationView does offer some additional functionality to a regular MKAnnotationView, such as animating while dragging and the 3d shadow effect. You won't get these if you use MKAnnotationView.
If you want these built-in features, you can create a UIImageView and add it as a subview to your MKPinAnnotationView. This will give you an annotation that looks like whatever you want; but behaves like a pin. I use it to replace the head of the pin with my own images.