I have code for drop pin. But i want to show title bar as in image above. How add images of star and review image?
use this delegate method
-(MKAnnotationView*)mapView:(MKMapView)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
// If you are showing the users location on the map you don't want to change it
MKAnnotationView *view = nil;
if (annotation != mapView.userLocation) {
// This is not the users location indicator (the blue dot)
view = [mapView dequeueReusableAnnotationViewWithIdentifier:#"myAnnotationIdentifier"];
if (!view) {
// Could not reuse a view ...
// Creating a new annotation view, in this case it still looks like a pin
view = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"myAnnotationIdentifier"] autorelease];
view.canShowCallOut = YES; // So that the callout can appear
UIImageView *myImageView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"someName"]];
myImageView.frame = CGRectMake(0,0,31,31); // Change the size of the image to fit the callout
// Change this to rightCallout... to move the image to the right side
view.leftCalloutAccessoryView = myImageView;
[myImageView release], myImageView = nil;
}
}
return view;
}
It's the same as with custom cells in TableView.
You just need to create new subclass of MKAnnotationView, and draw the view what you want.
Otherwise, you can try this tutorial to get custom callouts: http://dev.tuyennguyen.ca/?p=298
To do so, you have to put images in the annotation to make it customized, i think this article http://blog.asolutions.com/2010/09/building-custom-map-annotation-callouts-part-1 by James Rantanen can help you out.
- (MKAnnotationView *)mapView:(MKMapView *)mapViewTmp viewForAnnotation:(id<MKAnnotation>)annotation
{
if(annotation == mapView.userLocation)
return nil;
MKPinAnnotationView *pinView = (MKPinAnnotationView*)[mapViewTmp dequeueReusableAnnotationViewWithIdentifier:#"Pin"];
if (pinView ==nil) {
pinView = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:#"Pin"];
{
if([addedAnns containsObject:annotation]){
MyAnnotation *a = [addedAnns objectAtIndex:[addedAnns indexOfObject:annotation]];
UIImage * image = [UIImage imageNamed:a.pinImage];
UIImageView *imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
imageView.frame=[pinView bounds];
[pinView addSubview:imageView];
//[imageView release];
pinView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDeta`enter code here`ilDisclosure];
pinView.rightCalloutAccessoryView.tag = a.iAnnId;
[(UIButton *)pinView.rightCalloutAccessoryView addTarget:self action:#selector(openSpot:) forControlEvents:UIControlEventTouchUpInside];
pinView.enabled = YES;
pinView.centerOffset = CGPointMake(0,-15);
pinView.calloutOffset = CGPointMake(-8,0);
pinView.canShowCallout = YES;
}
}
pinView.animatesDrop = YES;
}
return pinView; // we cant release Or Auto release this object. Due To it will use futher
}
// The left accessory view to be used in the standard callout.
#property (retain, nonatomic) UIView *leftCalloutAccessoryView;
// The right accessory view to be used in the standard callout.
#property (retain, nonatomic) UIView *rightCalloutAccessoryView;
As you can see I am adding button to rightCalloutAccessoryView. Similarly you can Add Images To It.
You can use your custom MKAnnotationView.
Related
In MKAnnotation there are just title and subtitle, and i don't add anything control to annotation. How to I add a button?
Try using following delegate method of Map View. You can set right call out accessory view as button
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation{
MKAnnotationView *view = nil;
//MKPinAnnotationView *view=[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"HotSpotsLoc"];
if(annotation !=mapView.userLocation){
view = (MKAnnotationView *)
[mapView dequeueReusableAnnotationViewWithIdentifier:#"identifier"];
if(nil == view) {
view = [[[MKAnnotationView alloc]
initWithAnnotation:annotation reuseIdentifier:#"identifier"]
autorelease];
}
ParkPlaceMark *currPlaceMark = annotation;
NSLog(#"%i",currPlaceMark.position);
view.image = [UIImage imageNamed:#"pin.png"];
UIButton *btnViewVenue = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
view.rightCalloutAccessoryView=btnViewVenue;
view.enabled = YES;
view.canShowCallout = YES;
view.multipleTouchEnabled = NO;
//view.animatesDrop = YES;
}
return view;
}
Edit: Disregard this answer. Your complete question was not being shown because of bad markup and I extrapolated (incorrectly) what your question was.
You can drag anything onto the UITableViewCell you want to from the objects palette at right.
If you want to add it as the accessoryView however, do not do that.
Add it to the interface file as a separate top level object and drag a connection from the accessoryView outlet of the cell to the view/button you want.
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.
i have one view >> subview mkmapview .
in that i want to show image . ...my current image is like this.
and i want to show like this
how can i do this ? how can i add image in this anotation.
The image you're talking about corresponds to the leftCalloutAccessoryView property of MKAnnotationView.
Extract from the doc :
leftCalloutAccessoryView The view to
display on the left side of the
standard callout bubble.
You can implement a methods such as this :
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation {
MKAnnotationView* annotationView = nil;
MyAnnotation *myAnnotation = (MyAnnotation*) annotation;
NSString* identifier = #"Pin";
MKPinAnnotationView* annView = (MKPinAnnotationView*)[self.mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if(nil == annView) {
annView = [[[MKPinAnnotationView alloc] initWithAnnotation:myAnnotation reuseIdentifier:identifier] autorelease];
}
UIImageView *leftIconView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"LeftIconImage.png"]];
annView.leftCalloutAccessoryView = leftIconView;
return annotationView;
}
Hope this helps,
Vincent
In your MKAnnotationView set the leftCalloutAccessoryView property
leftCalloutAccessoryView The view to display on the left side of the
standard callout bubble.
#property (retain, nonatomic) UIView
*leftCalloutAccessoryView Discussion The default value of this property is
nil. The left callout view is
typically used to display information
about the annotation or to link to
custom information provided by your
application. The height of your view
should be 32 pixels or less.
If the view you specify is also a
descendant of the UIControl class, you
can use the map view’s delegate to
receive notifications when your
control is tapped. If it does not
descend from UIControl, your view is
responsible for handling any touch
events within its bounds.
Availability Available in iOS 3.0 and
later. See Also #property
canShowCallout Related Sample Code
MapCallouts Declared In
MKAnnotationView.h
Apple docs
v.leftCalloutAccessoryView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:#"img"]];
where v - is the view of your annotation(MKAnnotationView)
Or if you want complete solution - here it is:
- (MKAnnotationView *) mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>) annotation{
NSString *Identifier = [NSString stringWithFormat:#"%f%f",annotation.coordinate.latitude,annotation.coordinate.longitude];
MKPinAnnotationView *annView= (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:Identifier];
if (annView==nil) {
annView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:Identifier] autorelease];
}
if (![annotation isKindOfClass:[MyAnnotation class]]) {
return nil;
}
RightCalloutAccessoryBtn* rightButton = [RightCalloutAccessoryBtn buttonWithType:UIButtonTypeDetailDisclosure];
annView.rightCalloutAccessoryView = rightButton;
annView.leftCalloutAccessoryView = [[[UIImageView alloc] initWithImage:[UIImage imageNamed:#"img"]] autorelease];
annView.canShowCallout = YES;
return annView;
}
You should write this code on the class of your map's delegate
I'm displaying custom images on a map (instead of the default pins) using the code below. However, when I tap on an item (and the callout appears), the image reverts to the default red pin. How can I keep my custom image, even when the callout is displayed?
- (MKAnnotationView *) mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinAnnotation = nil;
if (annotation != mapView.userLocation)
{
static NSString *pinID = #"mapPin";
pinAnnotation = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:pinID];
if (pinAnnotation == nil)
pinAnnotation = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinID] autorelease];
// Set the image
pinAnnotation.image = [UIImage imageNamed:#"TestIcon.png"];
// Set ability to show callout
pinAnnotation.canShowCallout = YES;
// Set up the disclosure button on the right side
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinAnnotation.rightCalloutAccessoryView = infoButton;
[pinID release];
}
return pinAnnotation;
[pinAnnotation release];
}
I found by making the pinAnnotation a MKAnnotationView rather than a MKPinAnnotationView, I got the desired result. Image doesn't turn into a pin anymore
static NSString *pinID = #"mapPin";
pinAnnotation = (MKPinAnnotationView *)[mapView dequeueReusableAnnotationViewWithIdentifier:pinID];
if (pinAnnotation == nil)
pinAnnotation = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:pinID] autorelease];
// Set the image
pinAnnotation.image = [UIImage imageNamed:#"TestIcon.png"];
You need to use a subview rather than the image property. This code succssfully solves the problem for me:
UIImage * image = [UIImage imageNamed:#"blue_pin.png"];
UIImageView *imageView = [[[UIImageView alloc] initWithImage:image] autorelease];
[annView addSubview:imageView];
I'm trying to add an image behind a MKPinAnnotationView. Seems like it should be rather easy to just do this in here:
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
for (MKAnnotationView *aView in views)
[[aView superview] addSubview:imageView];
}
But the problem I am having in doing that is that the child subview to the pin will render on top of it not BEHIND it.
I have also tried:
for (MKAnnotationView *aView in views)
[[aView superview] insertSubview:imageView atIndex:1];
The problem with this is that, while it IS behind the pin, as soon as the map is repositioned, the image floats off the screen.
Any suggestions? Thanks
Thanks for the input, here's basically what I ended up doing without subclassing:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id )annotation {
MKAnnotationView *annView = [[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
UIImage *image = [UIImage imageNamed:#"image.png"];
UIImageView *imageView = [[UIImageView alloc] initWithImage:image];
[annView addSubview:imageView];
[imageView release];
MKPinAnnotationView *pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil];
[annView addSubview:pinView];
[pinView release];
return annView;
}
I only needed one pin, so I set reuseIdentifier to nil.
I have subclassed the MKAnnotatonView and overrode the initWithAnnotation:resueIdentifier and drawRect methods to add another image behind the "front" image.
It seems that that is what Apple's MKAnnotationView class reference is suggesting us to do.
Only that it is tricky. If you are subclassing the MKAnnotationView, there is still the image property existing. They have done something about the properly so that it is linked with drawing. Perhaps, they have overridden the drawRect to draw the image AFTER the initialization is done.
Also, if you don't set the image property, the frame of your custom annotationView is set to size 0, and the drawRect method does not get called.
Finally, Apple says that the images should be totally filled, i.e. uses a transparent colour for the background of the drawings.
So: In your subclass:
- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)identifier
{
self = [super initWithAnnotation:annotation reuseIdentifier:identifier];
if (self)
{
UIButton *rightButton = [UIButton buttonWithType: UIButtonTypeDetailDisclosure];
[rightButton addTarget:self
action:#selector(myShowAnnotationAddress:)
forControlEvents:UIControlEventTouchUpInside];
self.rightCalloutAccessoryView = rightButton;
self.canShowCallout = YES;
self.multipleTouchEnabled = NO;
self.frame = CGRectMake(0, 0, 65, 100);
self.backgroundColor = [UIColor clearColor];
return self;
}
return nil;
}
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSaveGState(context);
CGPoint drawPoint = CGPointMake(0.0f, 0.0f);
UIImage *shadowImage = [UIImage imageNamed:#"shadow_image.png"];
[shadowImage drawAtPoint:drawPoint];
UIImage *frontImage = [UIImage imageNamed:#"front_image.png"];
[frontImage drawAtPoint:drawPoint];
CGContextRestoreGState(context);
}
After I made the answer, I realize that you actually wanted to draw behind MKPinAnnotationView. My answer is not that, although it shows where the drawing perhaps should be done. Obviously MKPinAnnottions has its own drawing method to present a Pin and its shadow.
I think that probably you can retrieve the Pin image from the self.image property. As to the shadow, I am not certain... It may be using OPEN GL drawing method to add the shadow, or simply combining a shadow image.
Finally, the image comes with animation. I am guessing that that is where the animation is run. At this stage, though, I have not tested.
Create a new composite annotationview that first adds your image and then the actual MKAnnotationView:
#implementation MyCustomAnnotationView
- (void) viewDidLoad
{
// First add the image to our subviews
UIImageView *view = [[UIImageView alloc] initWithImage: myImageProperty];
[self.view addSubview: view];
[view release];
// Then add the MKAnnotationView on top of it
MKAnnotationView *annotation = [[MKAnnotationView alloc] init];
[self.view addSubview: annotation];
[annotation release];
}
#end