2010-11-30 8 views
30

Ich versuche, Tippen Ereignis auf meinem MKMapView zu erfassen, auf diese Weise kann ich eine MKPinAnnotation auf den Punkt fallen, wo Benutzer angezapft. Grundsätzlich habe ich eine Karte überlagert mit MKOverlayViews (eine Überlagerung, die ein Gebäude zeigt) und ich möchte Benutzer mehr Informationen über das Überlagern geben, wenn sie darauf tippen, indem Sie eine MKPinAnnotaion fallen lassen und mehr Information im Callout zeigen. Danke.Wie zu erfassen Tippen Geste auf MKMapView

Antwort

59

Sie können eine UIGestureRecognizer verwenden, um Berührungen in der Kartenansicht zu erkennen.

Statt einer einzigen tippen, würde ich vorschlagen, einen Doppelhahn (UITapGestureRecognizer) oder einen langen Druck (UILongPressGestureRecognizer) zu suchen. Ein einzelnes Antippen könnte den Benutzer stören, wenn er versucht, auf den Pin oder das Callout selbst einmal zu tippen.

An der Stelle, wo Sie das Setup der Kartenansicht (in viewDidLoad zum Beispiel), die Gestenerkenner in die Kartenansicht anhängen:

UITapGestureRecognizer *tgr = [[UITapGestureRecognizer alloc] 
    initWithTarget:self action:@selector(handleGesture:)]; 
tgr.numberOfTapsRequired = 2; 
tgr.numberOfTouchesRequired = 1; 
[mapView addGestureRecognizer:tgr]; 
[tgr release]; 

oder langes Drücken zu verwenden:

UILongPressGestureRecognizer *lpgr = [[UILongPressGestureRecognizer alloc] 
    initWithTarget:self action:@selector(handleGesture:)]; 
lpgr.minimumPressDuration = 2.0; //user must press for 2 seconds 
[mapView addGestureRecognizer:lpgr]; 
[lpgr release]; 


im handleGesture: Methode:

- (void)handleGesture:(UIGestureRecognizer *)gestureRecognizer 
{ 
    if (gestureRecognizer.state != UIGestureRecognizerStateEnded) 
     return; 

    CGPoint touchPoint = [gestureRecognizer locationInView:mapView]; 
    CLLocationCoordinate2D touchMapCoordinate = 
     [mapView convertPoint:touchPoint toCoordinateFromView:mapView]; 

    MKPointAnnotation *pa = [[MKPointAnnotation alloc] init]; 
    pa.coordinate = touchMapCoordinate; 
    pa.title = @"Hello"; 
    [mapView addAnnotation:pa]; 
    [pa release]; 
} 
+0

Vielen Dank für den Rat, sobald ich es funktioniert habe, werde ich so bald wie möglich antworten. Ich habe einen einzelnen Tipp versucht, aber danach konnte ich keine Callouts meiner PinAnnotations anzeigen. Sieht so aus, als müsste ich LongPressureGesture verwenden – sbkb

+4

Der UITapGestureRecognizer erkennt in MKMapView nicht mehr in iOS 6. Es funktionierte in iOS 5. Irgendwelche Ideen zu diesem Problem? – Felix

+6

@ phix23, versuchen Sie '' sollteRecognizeSimultlyouslyWithGestureRecognizer' zu implementieren und geben Sie 'YES' von dort zurück. Wird benötigt, um 'tgr.delegate = self;' vor dem Hinzufügen der GR für die shoudRecognize Delegate-Methode zu nennen. – Anna

5

Ich habe einen langen Druck (UILongPressGestureRecognizer) in viewDidLoad: eingerichtet, aber es erkennt nur die einzige Berührung von der ersten.

Wo kann ich einen langen Druck einstellen, um alle Berührungen zu erkennen? (es bedeutet, dass die Karte immer bereit ist, wenn der Benutzer auf den Bildschirm klickt, um einen Stift zu drücken)

Die Methode viewDidLoad:!

- (void)viewDidLoad { 
    [super viewDidLoad];mapView.mapType = MKMapTypeStandard; 

    UILongPressGestureRecognizer *longPressGesture = [[UILongPressGestureRecognizer alloc] initWithTarget:self action:@selector(handleLongPressGesture:)]; 
    [self.mapView addGestureRecognizer:longPressGesture]; 
    [longPressGesture release]; 

    mapAnnotations = [[NSMutableArray alloc] init]; 
    MyLocation *location = [[MyLocation alloc] init]; 
    [mapAnnotations addObject:location]; 

    [self gotoLocation]; 
    [self.mapView addAnnotations:self.mapAnnotations]; 
} 

und die handleLongPressGesture Methode:

-(void)handleLongPressGesture:(UIGestureRecognizer*)sender { 
    // This is important if you only want to receive one tap and hold event 
    if (sender.state == UIGestureRecognizerStateEnded) 
    {NSLog(@"Released!"); 
     [self.mapView removeGestureRecognizer:sender]; 
    } 
    else 
    { 
     // Here we get the CGPoint for the touch and convert it to latitude and longitude coordinates to display on the map 
     CGPoint point = [sender locationInView:self.mapView]; 
     CLLocationCoordinate2D locCoord = [self.mapView convertPoint:point toCoordinateFromView:self.mapView]; 
     // Then all you have to do is create the annotation and add it to the map 
     MyLocation *dropPin = [[MyLocation alloc] init]; 
     dropPin.latitude = [NSNumber numberWithDouble:locCoord.latitude]; 
     dropPin.longitude = [NSNumber numberWithDouble:locCoord.longitude]; 
//  [self.mapView addAnnotation:dropPin]; 
     [mapAnnotations addObject:dropPin]; 
     [dropPin release]; 
     NSLog(@"Hold!!"); 
     NSLog(@"Count: %d", [mapAnnotations count]); 
    } 
} 
1

Wenn Sie einen Klick/tap in der Kartenansicht verwenden möchten, hier ist ein Code-Snippet verwende ich. (Kakao und Swift)

let gr = NSClickGestureRecognizer(target: self, action: "createPoint:") 
gr.numberOfClicksRequired = 1 
gr.delaysPrimaryMouseButtonEvents = false // allows +/- button press 
gr.delegate = self 
map.addGestureRecognizer(gr) 

in der Geste Delegatmethode, ein einfacher Test der Doppel-Tap Geste bevorzugen ...

func gestureRecognizer(gestureRecognizer: NSGestureRecognizer, shouldRequireFailureOfGestureRecognizer otherGestureRecognizer: NSGestureRecognizer) -> Bool { 
    let other = otherGestureRecognizer as? NSClickGestureRecognizer 
    if (other?.numberOfClicksRequired > 1) { 
    return true; // allows double click 
    } 

    return false 
} 

Sie auch die Geste in anderen Delegatmethoden filtern können, wenn Sie das wollte Karte in verschiedenen "Staaten" zu sein, von denen einer erlaubt das einzige Tippen/Klicken