Détecter le tap sur le titre de la légende

comment puis-je détecter un tap sur le titre d'une légende d'une annotation? J'ai déjà un bon accessoire de légende et un autre à gauche, mais je veux détecter si un user appuie sur le titre (qui est au centre de la légende).

Si ce n'est pas possible, comment désactiver le masquage de la légende si j'appuie sur le titre?

il est un peu tard pour répondre à votre question, mais je fais face au même genre de problème récemment et je fais ma propre solution avec des essais et des erreurs. peut-être que je peux aider quelqu'un qui s'occupe du même problème.

vous pouvez également utiliser des classs d'affichage d'annotations et de légendes personnalisées, il existe de nombreux exemples. mais, il existe un autre moyen simple de résoudre ce problème sans utiliser les classs étrangères complexes.

définition du problème: je veux être capable de triggersr une méthode juste en touchant dans la vue des légendes. Je ne veux pas utiliser les buttons d'accesoire droit ou gauche. mais quand j'ai touché la légende, la vue disparaît immédiatement.

explication succincte de la solution: nous utilisons simplement "MKPinAnnotationView" personnalisé avec "hittest" pour détecter les touches dans la vue des légendes.

vous pouvez également find le lien du projet github à la fin de la publication.

touchableCallOutsViewController.h

// // touchableCallOutsViewController.h // touchableCallOuts // // Created by yasin turkoglu on 20.11.2012. // Copyright (c) 2012 yasin turkoglu. All rights reserved. // #import <UIKit/UIKit.h> #import <MapKit/MapKit.h> @class myCustomPinAnnotationClass; @interface touchableCallOutsViewController : UIViewController <MKMapViewDelegate> { MKMapView *myMapView; int pinCounter; myCustomPinAnnotationClass *myAnnotation; CLLocationCoordinate2D selectedPinCoordinate; int selectedPinNumber; } @property (strong, nonatomic) MKMapView *myMapView; @property (strong, nonatomic) myCustomPinAnnotationClass *myAnnotation; @end 

touchableCallOutsViewController.m

 // // touchableCallOutsViewController.m // touchableCallOuts // // Created by yasin turkoglu on 20.11.2012. // Copyright (c) 2012 yasin turkoglu. All rights reserved. // #import "touchableCallOutsViewController.h" #import "myCustomPinAnnotationClass.h" @interface touchableCallOutsViewController () @end @implementation touchableCallOutsViewController @synthesize myMapView; @synthesize myAnnotation; - (void)viewDidLoad { //first we create mapview and add pin annotation myMapView = [[MKMapView alloc]initWithFrame:self.view.frame]; myMapView.delegate = self; MKCoordinateRegion region = {{0,0},{1.0,1.0}}; region.center.latitude = 41.036651; //user defined region.center.longitude = 28.983870;//user defined [myMapView setRegion:region animated:YES]; [self.view addSubview:myMapView]; //we define long press recognizer for 2 seconds and add our map view to add new pin when you press 2 seconds on map view UILongPressGestureRecognizer *lngPrs = [[UILongPressGestureRecognizer alloc]initWithTarget:self action:@selector(handleMyLongPress:)]; lngPrs.minimumPressDuration = 2.0; [myMapView addGestureRecognizer:lngPrs]; pinCounter = 1; //this variable hold pin numbers and increment 1 when new pin added. myAnnotation = [[myCustomPinAnnotationClass alloc]initWithName:[NSSsortingng ssortingngWithFormat:@"Pin %i",pinCounter] description:@"touch here to see pin coordinates" pinNum:pinCounter coordinate:region.center]; [myMapView addAnnotation:myAnnotation]; } - (void)handleMyLongPress:(UIGestureRecognizer *)gestureRecognizer { if (gestureRecognizer.state != UIGestureRecognizerStateBegan) { }else{ //when we press more than 2 seconds on map view UILongPressGestureRecognizer sortingggered this method and call our custom MKPinAnnotationView class and add annotation. CGPoint touchPoint = [gestureRecognizer locationInView:myMapView]; CLLocationCoordinate2D touchMapCoordinate = [myMapView convertPoint:touchPoint toCoordinateFromView:myMapView]; pinCounter++; myAnnotation = [[myCustomPinAnnotationClass alloc]initWithName:[NSSsortingng ssortingngWithFormat:@"Pin %i",pinCounter] description:@"touch here to see pin coordinates" pinNum:pinCounter coordinate:touchMapCoordinate]; [myMapView addAnnotation:myAnnotation]; } } - (MKAnnotationView *)mapView:(MKMapView *)mapView viewForAnnotation:(id<MKAnnotation>)annotation { //when new annotation added by us, new annotation property will set here static NSSsortingng *identifier = @"myPins"; if ([annotation isKindOfClass:[myCustomPinAnnotationClass class]]) { myCustomPinAnnotationClass *annotationView = (myCustomPinAnnotationClass *) [self.myMapView dequeueReusableAnnotationViewWithIdentifier:identifier]; if (annotationView == nil) { annotationView = [[myCustomPinAnnotationClass alloc] initWithAnnotation:annotation reuseIdentifier:identifier]; } else { annotationView.annotation = annotation; } myAnnotation = (myCustomPinAnnotationClass *)annotation; annotationView.pinColor = MKPinAnnotationColorGreen; annotationView.enabled = YES; annotationView.draggable = YES; annotationView.canShowCallout = YES; [annotationView setSelected:YES animated:YES]; return annotationView; } return nil; } - (void)mapView:(MKMapView *)mapView didSelectAnnotationView:(MKAnnotationView *)view { //if you select any annotation to show their callout sellected annotation pin number and coordinate setted and call findcallot method myAnnotation = (myCustomPinAnnotationClass *)view.annotation; selectedPinCoordinate = myAnnotation.coordinate; selectedPinNumber = myAnnotation.pinNum; [self findCallOut:myMapView]; } - (void)findCallOut:(UIView *)node { //this method dig our mapview with for loop until find callout view class named "UICalloutView" if([node isKindOfClass:[NSClassFromSsortingng(@"UICalloutView") class]]){ //this method sortinggered together with callout open animation. //in UICalloutView we have callout bubble image //we dig it with for loop to find this image height float buubleHeight = 0.0; for(UIImageView *bubbleComponents in node.subviews){ //when we find callout bubble image take height to set our touchable area height buubleHeight = bubbleComponents.frame.size.height; break; } //this method sortingger with callout open animation as I said before //ant this bouncing open animation distort actual size of callout view //so when this happens we also get transform value of callout view and make proportion to find exact sizes. CGFloat nodeTransformRatio = node.transform.a; CGFloat calculatedWidth = roundf(node.frame.size.width / nodeTransformRatio); CGFloat calculatedHeight = roundf(buubleHeight / nodeTransformRatio); //now create a new UIView and sized according to callout view. UIView *touchableView = [[UIView alloc]initWithFrame:CGRectMake(0.0, 0.0, calculatedWidth, calculatedHeight)]; touchableView.userInteractionEnabled = YES; //we add new single tap gesture recognizer to sortingger desired method when users touching to the callout UITapGestureRecognizer *singleTap = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(doSomething)]; [touchableView addGestureRecognizer:singleTap]; //and finaly we add this newly created view in callout view to receive touches. [node addSubview:touchableView]; }else{ //loop self until find a "UICalloutView" for(UIView *child in node.subviews){ [self findCallOut:child]; } } } - (void)doSomething { //this method call allert view our preseted variables when users touch callout view. UIAlertView *alertHolder = [[UIAlertView alloc] initWithTitle:[NSSsortingng ssortingngWithFormat:@"You're touched the Pin %i CallOut",selectedPinNumber] message:[NSSsortingng ssortingngWithFormat:@"lat : %f\nlong : %f",selectedPinCoordinate.latitude,selectedPinCoordinate.longitude] delegate:self cancelButtonTitle:nil otherButtonTitles:@"ok",nil]; [alertHolder show]; } - (void)didReceiveMemoryWarning { [super didReceiveMemoryWarning]; // Dispose of any resources that can be recreated. } @end 

myCustomPinAnnotationClass.h

 // // myCustomPinAnnotationClass.h // touchableCallOuts // // Created by yasin turkoglu on 20.11.2012. // Copyright (c) 2012 yasin turkoglu. All rights reserved. // #import <MapKit/MapKit.h> @interface myCustomPinAnnotationClass : MKPinAnnotationView <MKAnnotation> { NSSsortingng *_name; NSSsortingng *_description; int _pinNum; CLLocationCoordinate2D _coordinate; } @property (copy) NSSsortingng *name; @property (copy) NSSsortingng *description; @property (nonatomic, readonly) int pinNum; @property (nonatomic, readonly) CLLocationCoordinate2D coordinate; - (id)initWithName:(NSSsortingng*)header description:(NSSsortingng*)description pinNum:(int)pinNum coordinate:(CLLocationCoordinate2D)coordinate; @end 

myCustomPinAnnotationClass.m

 // // myCustomPinAnnotationClass.m // touchableCallOuts // // Created by yasin turkoglu on 20.11.2012. // Copyright (c) 2012 yasin turkoglu. All rights reserved. // #import "myCustomPinAnnotationClass.h" @implementation myCustomPinAnnotationClass @synthesize name = _name; @synthesize description = _description; @synthesize pinNum = _pinNum; @synthesize coordinate = _coordinate; - (id)initWithName:(NSSsortingng*)header description:(NSSsortingng*)description pinNum:(int)pinNum coordinate:(CLLocationCoordinate2D)coordinate { self = [super init]; if (self) { _name = [header copy]; _description = [description copy]; _pinNum = pinNum; _coordinate = coordinate; } return self; } - (void)setCoordinate:(CLLocationCoordinate2D)newCoordinate { _coordinate = newCoordinate; } - (NSSsortingng *)title { return _name; } - (NSSsortingng *)subtitle { return _description; } - (int)tag { return _pinNum; } -(UIView*)hitTest:(CGPoint)point withEvent:(UIEvent*)event { //test touched point in map view //when hit test return nil callout close immediately by default UIView* hitView = [super hitTest:point withEvent:event]; // if hittest return nil test touch point if (hitView == nil){ //dig view to find custom touchable view lately added by us for(UIView *firstView in self.subviews){ if([firstView isKindOfClass:[NSClassFromSsortingng(@"UICalloutView") class]]){ for(UIView *touchableView in firstView.subviews){ if([touchableView isKindOfClass:[UIView class]]){ //this is our touchable view class //define touchable area CGRect touchableArea = CGRectMake(firstView.frame.origin.x, firstView.frame.origin.y, touchableView.frame.size.width, touchableView.frame.size.height); //test touch point if in touchable area if (CGRectContainsPoint(touchableArea, point)){ //if touch point is in touchable area return touchable view as a touched view hitView = touchableView; } } } } } } return hitView; } @end 

Ici vous pouvez download la list complète des projets avec le code source https://github.com/ytur/touchableCallOutsForIOSMaps