I try to call a method when the annotation view (and only the annotation view) is clicked.
- (void)mapView:(MKMapView *)m didSelectAnnotationView:(MKAnnotationView *)view {
[self openDetailView];
}
But what i noticed, is that this method (openDetailView) is called only when i select the PIN, means before the annotation view gets displayed. How can i fire that method on callout click? Thanx in advance.
By adding button with arrow instead of callout:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation {
if ([annotation isMemberOfClass:[MKUserLocation class]]) {
return nil;
}
MKPinAnnotationView *v =[[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"ku"] autorelease];
UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
button.frame = CGRectMake(0, 0, 24, 24);
Shop *shop = [(ShopAnnotation *)annotation myShop];
button.tag = [shop.ID intValue];
[button addTarget:self action:#selector(callOutPressed:) forControlEvents:UIControlEventTouchUpInside];
[button setImage:[UIImage imageNamed:#"map_arr_right.png"] forState:UIControlStateNormal];
v.rightCalloutAccessoryView = button;
v.canShowCallout = YES;
return v;
}
- (void) callOutPressed:(id)sender {
NSLog(#"callout pressed");
}
Related
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation {
MKAnnotationView *view = [self.mapView dequeueReusableAnnotationViewWithIdentifier:#"loc"];
return view;
}
- (void)mapView:(MKMapView *)mapView didAddAnnotationViews:(NSArray *)views {
for (MKAnnotationView *annotationView in views) {
annotationView.canShowCallout = NO;
}
}
- (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view {
MAKRCalloutView *calloutView = [[MAKRCalloutView alloc] initWithNibName:#"ViewM" bundle:nil];
UIButton *btn = [[UIButton alloc]initWithFrame:CGRectMake(10.0, 10.0, 50.0, 50.0)];
[btn setBackgroundColor:[UIColor redColor]];
[btn addTarget:self action:#selector(buttonClicked:) forControlEvents:UIControlEventTouchUpInside];
[view addSubview:calloutView.view];
[view addSubview:btn];
}
-(void) buttonClicked:(id)sender{
NSLog(#" %ld button click %# ", (long)[sender tag]);
}
- (void)mapView:(MKMapView *)mapView didDeselectAnnotationView:(MKAnnotationView *)view {
for (UIView *subview in view.subviews) {
MAKRCalloutView *calloutView = [[MAKRCalloutView alloc] initWithNibName:#"ViewM" bundle:nil];
if (![subview isKindOfClass:[calloutView.view class]]) {
continue;
}
[subview removeFromSuperview];
}
}
I cannot call get button click event. Even I cannot click on button also. I want to go at other UIViewController by click on button.
I have also tried UITapGestureRecognizer. But its limited to Pin area only.
[button addTarget:self action:#selector(clickEvent) forControlEvents:UIControlEventTouchDown]
And then
- (CustomAnnotationView *)mapView:(MKMapView *)aMapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[CustomAnnotation class]])
{
CustomAnnotationView *newAnnotationView = nil;
// determine the type of annotation, and produce the correct type of annotation view for it.
newAnnotationView = [[[CustomAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:nil delegate: targetController] autorelease];
[newAnnotationView setEnabled:YES];
[newAnnotationView setCanShowCallout:NO];
return newAnnotationView;
}
}
#interface CustomAnnotationView : MKAnnotationView
{
}
#end
#implementation CustomAnnotationView
- (id)initWithAnnotation:(id <MKAnnotation>)annotation reuseIdentifier:(NSString *)reuseIdentifier delegate:(id)targetController
{
self = [super initWithAnnotation:annotation reuseIdentifier:reuseIdentifier];
/* Set initial width as you want. ex: 50X50*/
self.frame = CGRectMake(0, 0, Initial_width, Initial_height);
self.backgroundColor = [UIColor redColor];
return self;
}
/* When you tap on an annotation this method is fired*/
- (void)setSelected:(BOOL)selected animated:(BOOL)animated
{
if(selected){
/* When you select annotation, instead of showing default callout you can increase the width &height of annotation and add your custom view here*/
self.frame = CGRectMake(0, 0, max_width, max_height);
UIView *view = [[UIView alloc]initWithFrame:CGRectMake(6, 0, max_width-10, max_height)];
view.backgroundColor = [UIColor blackColor];
UIButton *but = [UIButton buttonWithType:UIButtonTypeCustom];
UIImage *img = [UIImage imageNamed:#"image.png"];
but = CGRectMake(x , y, img.size.width + 20, img.size.height + 15);
[but setImage:img forState:UIControlStateNormal];
[but addTarget:targetController action:#selector(methodName) forControlEvents:UIControlEventTouchDown];
[view addSubview:but];
[self addSubview:view];
}
else {
/* When you tap outside of annotation, set the initial frame for the annotation. and remove the custom view from annotation*/
self.frame = CGRectMake(0, 0, Initial_width, Initial_height);
[view removeFromSuperview];
}
}
My annotations trigger the right actions, but they aren't showing the right accessory button no matter which button I choose. Below is my code.
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation{
static NSString *s = #"ann";
MKAnnotationView *pin = [mapView dequeueReusableAnnotationViewWithIdentifier:s];
if (annotation != self.mapView.userLocation) {
pin = [[MKPinAnnotationView alloc]initWithAnnotation:annotation reuseIdentifier:s];
pin.canShowCallout = YES;
pin.calloutOffset = CGPointMake(0, 0);
UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pin.rightCalloutAccessoryView = button;
[button addTarget:self
action:#selector(getDirections:)
forControlEvents:UIControlEventTouchUpInside];
}
return pin;
}
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;
// Handle any custom annotations.
MKAnnotationView *pin = [mapView dequeueReusableAnnotationViewWithIdentifier:#"ann"];
if(pin){
pin.annotation = annotation;
} else {
pin = [[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:#"ann"];
}
pin.canShowCallout = YES;
pin.calloutOffset = CGPointMake(0, 0);
UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
pin.rightCalloutAccessoryView = button;
[button addTarget:self
action:#selector(getDirections:)
forControlEvents:UIControlEventTouchUpInside];
return pin;
}
I am adding a button to annotation callout. On click event of button, I want to push another View Controller with details of annotation like title and subtitle. However, the problem is I am not able to get these details.
Here's what I did so far:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)userannotation
{
if ([annotation isMemberOfClass:[MKUserLocation class]])
{
return nil;
}
MKPinAnnotationView *v =[[MKPinAnnotationView alloc] initWithAnnotation:userannotation reuseIdentifier:#"ku"];
UIButton *button = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
button.frame = CGRectMake(0, 0, 24, 24);
// [button addTarget:self action:#selector(callOutPressed:) forControlEvents:UIControlEventTouchUpInside];
v.rightCalloutAccessoryView = button;
v.canShowCallout = YES;
return v;
}
/*
- (void) callOutPressed:(id)sender
{
[ dict setValue:annotation.subtitle forKey:#"jid"] ;
[dict setValue:annotation.title forKey:#"name"];
NSLog(#"annotation values - %#",dict); // this shows null
*/
Okay. I tried using this:
- (void)mapView:(MKMapView *)mapView annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
NSLog(#"display name :-%#", view.annotation.title);// shows name
[dict setValue:view.annotation.title forKey:#"name"];//dict shows 0 key/value pairs and the app crashes.
NSLog(#"output :-%#", dict); //shows null
}
What is the correct way to do it?
I have a detailDisclousure button on the callout of a MKAnnotation. When this button is pressed I need to call a method passing a parameter that identifies the annotation that called it. How could it be done?
this is my viewForAnnotation:
- (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[Annotation class]])
{
static NSString* identifier = #"identifier";
MKPinAnnotationView* pinView = (MKPinAnnotationView*)[mapView dequeueReusableAnnotationViewWithIdentifier:identifier];
if (pinView == nil)
{
pinView = [[[MKPinAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:identifier]autorelease];
}
Annotation *antt = annotation;
pinView.canShowCallout = YES;
pinView.draggable = YES;
UIButton* detailButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[detailButton performSelector:#selector(goToViewWithAnnotation:) withObject:antt];
pinView.rightCalloutAccessoryView = detailButton;
return pinView;
}
else
{
return nil;
}
}
And this is the method that should be called with the parameter:
-(void)goToViewWithAnnotation:(Annotation *)annotation
{
NextViewController *nextView = [[NextViewController alloc]initWithNibName:#"NextViewController" bundle:nil];
nextView.id = annotation.id;
[self.navigationController nextView animated:YES];
}
you can pass any NSInteger via the tag property of the UIButton only.
It's not possible to send data with the -addTarget:action:forControlEvent: for UIButton:
[detailButton addTarget:self action:#selector(goToViewWithAnnotation:) forControlEvents:UIControlEventTouchUpInside];
Try to handle the data with some other way, when you trigger the selector. Like saving a pointer or var as you like.
UIButton have these callers as you can see:
- (void)action
- (void)action:(id)sender
- (void)action:(id)sender forEvent:(UIEvent *)event
I think you can add a property(which is (Annotation *)annotation) in .h file. Then you can use annotation in the "-(void)goToViewWithAnnotation" method. Or you can customized a new button which inherits UIControl
Here's a sample custom callout that I'd want to get a similar style of. I was thinking of inheriting from MKAnnotation but I'm lost how to start it and I don't know if the callout's design could be overridden.
Any ideas how to implement this custom callout with ui controls inside?
EDIT: Here's my code from following the similar StackOverflow answer:
- (MKAnnotationView *)mapView:(MKMapView *)mapview viewForAnnotation:(id <MKAnnotation>)annotation
{
if ([annotation isKindOfClass:[MKUserLocation class]])
return nil;
static NSString* AnnotationIdentifier = #"AnnotationIdentifier";
MKAnnotationView *annotationView = [mapView dequeueReusableAnnotationViewWithIdentifier:AnnotationIdentifier];
if(annotationView)
return annotationView;
else
{
UIImage *img = [UIImage imageNamed:#"default_thumb.png"];
MKAnnotationView *annotationView =
[[MKAnnotationView alloc] initWithAnnotation:annotation reuseIdentifier:AnnotationIdentifier];
annotationView.canShowCallout = YES;
annotationView.image = img;
annotationView.draggable = YES;
/*
// change left accessory view button with image
UIImageView *leftAccView = [[UIImageView alloc] initWithImage:img];
annotationView.leftCalloutAccessoryView = leftAccView;
//include a right button to show more info
UIButton* rightButton = [UIButton buttonWithType:UIButtonTypeDetailDisclosure];
[rightButton addTarget:self action:#selector(calloutSubMenu:) forControlEvents:UIControlEventTouchUpInside];
[rightButton setTitle:annotation.title forState:UIControlStateNormal];
annotationView.rightCalloutAccessoryView = rightButton;
*/
return annotationView;
}
return nil;
}
// Customize accessory view
- (void)mapView:(MKMapView *)mapview annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
{
[mapview deselectAnnotation:view.annotation animated:YES];
PopOverCallout *popOverCallout = [[PopOverCallout alloc]init];
UIPopoverController *popOver = [[UIPopoverController alloc] initWithContentViewController:popOverCallout];
self.annotationPopoverController = popOver;
popOver.popoverContentSize = CGSizeMake(500, 500);
[popOver presentPopoverFromRect:view.bounds inView:view permittedArrowDirections:UIPopoverArrowDirectionAny animated:YES];
}
The
(void)mapView:(MKMapView *)mapview annotationView:(MKAnnotationView *)view calloutAccessoryControlTapped:(UIControl *)control
should be called whenever the pin is touched to show the callout right? but what happens is that a blank regular callout is shown. What might I be doing wrong?
BTW: the UIViewController subclass only has a label on it's XIB and is pretty much blank.
Found out the answer after a few mins of nap.
using this as the guide, I just needed to override
-(void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view
which shows the annotation callout. Thanks again for the answer, Ms. Anna.