I have a view containing a MKMapView, I display sereval pins in it:
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
NSLog(#"mapView:viewForAnnotation");
// if it's the user location, just return nil.
if ([annotation isKindOfClass:[MKUserLocation class]]){
return nil;
}
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKPinAnnotationView *pinView = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
pinView.canShowCallout = YES;
pinView.pinColor = MKPinAnnotationColorPurple;
pinView.annotation = annotation;
return pinView;
}
This is working fine but the method:
-(void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
is not called when the pin is clicked. It seems the click event is not transmitted to the pin but I cannot figure out why. Any idea ?
When the pin itself is clicked, the map view will call the delegate method mapView:didSelectAnnotationView:.
The calloutAccessoryControlTapped method is called when an annotation view's leftCalloutAccessoryView or rightCalloutAccessoryView is tapped. These are controls (usually buttons) that appear on the pin's callout.
It sounds like you are looking for the mapView:didSelectAnnotationView: delegate method instead.
Related
i have added a detail button on my pin annotation. i want to go to another view. when i click on it, following code doesn't work. i don't know where is the problem.
- (MKAnnotationView *)mapView:(MKMapView *)mV viewForAnnotation:(id <MKAnnotation>)annotation
{
MKPinAnnotationView *pinAnnotation = nil;
if(annotation != mapview.userLocation)
{
static NSString *defaultPinID = #"myPin";
pinAnnotation = (MKPinAnnotationView *)[mapview dequeueReusableAnnotationViewWithIdentifier:defaultPinID];
if ( pinAnnotation == nil )
pinAnnotation = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:defaultPinID] autorelease];
pinAnnotation.canShowCallout = YES;
//instatiate a detail-disclosure button and set it to appear on right side of annotation
UIButton *infoButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pinAnnotation.rightCalloutAccessoryView = infoButton;
}
return pinAnnotation;
}
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
if ([(UIButton*)control buttonType] == UIButtonTypeDetailDisclosure){
annotationViewController *detailView=[[annotationViewController alloc] initWithNibName:#"annotationViewController" bundle:nil];
[[self navigationController] pushViewController:detailView animated:YES];
[detailView release];
}
}
The method - (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control is a delegate method. That's why you need to set your mapview's delegate to the class that implements this method (here self), in order for it to be called.
You also need to tell the class that you're implementing the MKMapViewDelegate methods. To do so, in you .h, change this line :
#interface MyViewController : UIViewController
To :
#interface MyViewController : UIViewController <MKMapViewDelegate>
Your method should get called now.
I am new to mapkit in objective-c. I am able to add custom annotation in mapview.
i need to place custom callout view like below image
.
But i didn't get how can i design callout view like this.
i know i need to add callout in view for annotation method.
- (MKAnnotationView *)mapView:(MKMapView *)map 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:#"blue_without_pin.png"];
annotationView.annotation = annotation;
return annotationView;
}
Basically what you want to do is add a new custom view by implementing the following method in your MKMapViewDelegate instance :
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
CGPoint annotationCenter = [mapView convertCoordinate:view.annotation.coordinate toPointToView:mapView];
[self displayCustomCalloutForAnnotation:view.annotation center:annotationCenter];
}
#interface CustomAnnotaionView : MKAnnotationView
#property (strong, nonatomic) UIView *calloutView;
-(void)setSelected:(BOOL)selected animated:(BOOL)animated;
#end
#implementation CustomAnnotaionView
#synthesize calloutView = _calloutView;
-(void)setSelected:(BOOL)selected animated:(BOOL)animated
{
[super setSelected:selected animated:animated];
if(selected)
{
[self.calloutView setFrame:CGRectMake(30, 130, 250, 135)];
[self.calloutView sizeToFit];
self.calloutView.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"popup.png"]];
[self addSubview:self.calloutView];
}
else
{
[self.calloutView removeFromSuperview];
}
}
-(void)didAddSubview:(UIView *)subview
{
if([[[subview class]description]isEqualToString:#"UICalloutView"])
{
[subview removeFromSuperview];
}
}
Use this customAnnotationView class in MapView delegate method,
- (MKAnnotationView *)mapView:(MKMapView *)theMapView viewForAnnotation:(id
<MKAnnotation>)annotation
{
if([annotation isKindOfClass:[MapAnnotation class]])
{
CustomAnnotationView *annotationView = (CustomAnnotaionView*)[theMapView dequeueReusableAnnotationViewWithIdentifier:#"CustomAnnotationView"];
if(!annotationView)
{
MapAnnotation *annotation = (MapAnnotation *)annotation;
annotationView = [[CustomAnnotaionView alloc]initWithAnnotation:annotation reuseIdentifier:#"CustomAnnotationView"];
[annotationView setCanShowCallout:YES];
}
else
annotationView.annotation = annotation;
return annotationView;
}
return nil;
}
One solution for this would be to detect the exact coordinate of the annotation selected relative to the parent UIView and then drawing a UIView directly on top of the MKMapView.
Here's a snippet that might help:
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
{
CGPoint pointInMap = [self.mapView convertCoordinate:buildingAnnotation.coordinate
toPointToView:self.view];
// Hide the default callout generated by MKMapView
[mapView deselectAnnotation:view.annotation animated:NO];
// Create a custom callout view and center the arrow on the pointInMap CGPoint
}
You must implement a callout view yourself, and use
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
this delegate to make the callout view showing at right place,
IOS have not any method to custom callout view yet
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;
}
}
Hello friends,
I want to develop a functionality MKMapView in iPhone and to show the custom pin in MKAnnotation so please could anyone provide me a link or any idea about this functionality.
Thanks in advance.
You would need to specify annotation image in the viewForAnnotation delegate method
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation {
static NSString * const kAnnotationId = #"VumeliveAnnotation";
MKPinAnnotationView *annotationView = nil;
if ([annotation isKindOfClass:[CustomAnnotation class]])
{
annotationView = (MKPinAnnotationView *)[self.mapView dequeueReusableAnnotationViewWithIdentifier:kAnnotationId];
if (annotationView == nil) {
annotationView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:kAnnotationId] autorelease];
annotationView.canShowCallout = YES;
annotationView.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
}
[annotationView setImage:[UIImage imageNamed:<your image name>]];
}
return annotationView;
}
In my MapView i have pin dropped on certain locations and now i want to display some title on these pin annotation and make it clickable so that on click i can push another view.
Please help !!!!
This is the code snippet:
Custom Annotation View using this method
- (MKAnnotationView *)mapView:(MKMapView *)map viewForAnnotation:(id <MKAnnotation>)annotation
{
if (annotation == mapView.userLocation) return nil;
MKPinAnnotationView *pin = (MKPinAnnotationView *) [mapView dequeueReusableAnnotationViewWithIdentifier: #"asdf"];
if (pin == nil)
{
pin = [[[MKPinAnnotationView alloc] initWithAnnotation: annotation reuseIdentifier: #"asdf"] autorelease];
}
else
{
pin.annotation = annotation;
}
pin.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pin.pinColor = MKPinAnnotationColorRed;
pin.animatesDrop = YES;
[pin setEnabled:YES];
[pin setCanShowCallout:YES];
return pin;
}
Delegate method which get's called when you tap on the button
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
//DetailPg=[[BookMarksDetail alloc]initWithNibName:#"BookMarksDetail" bundle:nil];
//DetailPg.selectRest =[view.annotation title]; //In addition, to get the Title of the AnnotationView.
//DetailPg.m=1;
//[self.navigationController pushViewController:DetailPg animated:YES];
//[DetailPg release];
}
The answers to this are all provided in Apples Docs I suggest you read them more closely. However to have a call out all you need to do is set the title property.
For buttons and such you need to use the MapView Delegate method:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
_pin.rightCalloutAccessoryView = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
Apple suggests reusing annotations this is something you will need to take into account.