59 votes

Comment ajouter une punaise à un MKMapView(IOS) en cas de contact ?

Je devais obtenir les coordonnées d'un point où l'utilisateur touche un MKMapView. Je ne travaille pas avec l'Interface Builder. Pouvez-vous me donner un exemple ?

195voto

Anna Points 44332

Vous pouvez utiliser un UILongPressGestureRecognizer pour ça. Partout où vous créez ou initialisez le mapview, attachez-y d'abord le recognizer :

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

Puis dans le gestionnaire de gestes :

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

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

    YourMKAnnotationClass *annot = [[YourMKAnnotationClass alloc] init];
    annot.coordinate = touchMapCoordinate;
    [self.mapView addAnnotation:annot];
    [annot release];
}

VotreMKAnnotationClass est une classe que vous définissez et qui est conforme à l'approche de la MKAnnotation protocole. Si votre application ne fonctionne que sur iOS 4.0 ou ultérieur, vous pouvez utiliser le protocole prédéfini MKPointAnnotation à la place.

Pour des exemples sur la création de votre propre classe MKAnnotation, voir l'exemple d'application MapCallouts .

7 votes

Excellente réponse, merci. Personnellement, j'ai inversé l'instruction if en une instruction == donc il retourne s'il n'est pas UIGestureRecognizerStateBegan . En procédant ainsi, l'épingle tombera après le temps spécifié, même si l'utilisateur tient toujours la carte en main, ce qui était souhaitable pour moi (et la façon dont l'application officielle Maps le fait).

0 votes

Je voudrais simplement dire que j'ai mis en œuvre votre réponse dans mon projet et que cela a fonctionné comme un charme. Merci pour votre excellente réponse.

0 votes

Cela fonctionne parfaitement mais seulement dans le simulateur pour moi. Pas de rappel sur le téléphone physique. Avez-vous des idées ? J'utilise iOS5 avec ARC.

34voto

Vlad Spreys Points 1073

Merci à Anna d'avoir fourni une si bonne réponse ! Voici une version Swift si cela intéresse quelqu'un (la réponse a été mise à jour pour la syntaxe Swift 4.1).

Création de UILongPressGestureRecognizer :

let longPressRecogniser = UILongPressGestureRecognizer(target: self, action: #selector(MapViewController.handleLongPress(_:)))
longPressRecogniser.minimumPressDuration = 1.0
mapView.addGestureRecognizer(longPressRecogniser)

Manipuler le geste :

@objc func handleLongPress(_ gestureRecognizer : UIGestureRecognizer){
    if gestureRecognizer.state != .began { return }

    let touchPoint = gestureRecognizer.location(in: mapView)
    let touchMapCoordinate = mapView.convert(touchPoint, toCoordinateFrom: mapView)

    let album = Album(coordinate: touchMapCoordinate, context: sharedContext)

    mapView.addAnnotation(album)
}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X