6 votes

Comment puis-je détecter si singleTap a été tapé ou annotation sur mapView de mapbox?

Exigence sur iOS pour la carte MapBox. (Je ne parle pas de MKMapView) Comment pouvons-nous détecter si un singleTap a été effectué ou une annotation sur la mapView ? J'ai besoin que le singleTap soit géré uniquement sur une zone vide de la carte (sans broches), et didSelectAnnotation soit appelé lorsque je tape sur une broche.

Mais j'ai trouvé sur Android une méthode comme celle-ci

mapboxMap.setOnMapClickListener(new MapboxMap.OnMapClickListener() {
            public void onMapClick(@NonNull LatLng point) {
                Toast.makeText(getActivity(),"sur Tap "+point.getLatitude(),Toast.LENGTH_LONG).show();
            }
        });

et en plus de cela

mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() { ... }) affichera l'annotation.

N'avons-nous pas le même genre de concept sur iOS ?

Le véritable problème sur iOS est que, lorsque j'ajoute singleTapGesture sur mapView de Mapbox

UITapGestureRecognizer *singleTapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(handleSingleTap:)];
[self.mapView addGestureRecognizer:singleTapGesture];

la méthode déléguée de mapView de mapbox ne sera pas appelée.

- (nullable UIView  *)mapView:(MGLMapView *)mapView calloutViewForAnnotation:(id )annotation;

pour garantir que la méthode déléguée soit appelée, alors je n'ai pas à utiliser singleTapGesture

Ici, la situation est soit ceci, soit cela, mais selon moi, j'avais besoin des deux.

En attente de toute solution. Merci,

0voto

iNasir Points 332

Voici quelques astuces qui m'ont aidé à répondre à mes besoins. Selon mon besoin, je suis capable de détecter un seul clic à la fois sur le marqueur d'annotation de mapbox et sur la zone vide de la carte

J'ai créé une catégorie pour MGLMapView, (MGLMapView+EDCMapboxView) et j'ai remplacé les méthodes de toucher

-touchesBegan:withEvent:
-touchesMoved:withEvent:
-touchesEnded:withEvent:
-touchesCancelled:withEvent:

MGLMapView+EDCMapboxView.h

@protocol EDCMapboxViewDelegate 
@optional
- (void)mapboxViewDidCreateNewTicket:(MGLMapView*)mapView;
@end

@interface MGLMapView (EDCMapboxView)

@property (assign, nonatomic) BOOL shouldCreateNewTicket;

@property (weak, nonatomic) id  mapboxDelegate;
@end

MGLMapView+EDCMapboxView.m

@implementation MGLMapView (EDCMapboxView)
@dynamic mapboxDelegate;

#pragma mark -- Accessor
- (BOOL)shouldCreateNewTicket {
    return [objc_getAssociatedObject(self, @selector(shouldCreateNewTicket)) boolValue];
}
- (void)setShouldCreateNewTicket:(BOOL)flag {
    objc_setAssociatedObject(self, @selector(shouldCreateNewTicket), @(flag), OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

-(id)mapboxDelegate{
    return objc_getAssociatedObject(self, @selector(mapboxDelegate));
}
- (void)setMapboxDelegate:(id)mapboxDelegate{
    objc_setAssociatedObject(self, @selector(mapboxDelegate), mapboxDelegate, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}

#pragma mark -- Méthode surchargée pour UIResponder
- (void)touchesBegan:(NSSet *)touches withEvent:(nullable UIEvent *)event{
    NSLog(@"touchesBegan");
}

- (void)touchesMoved:(NSSet *)touches withEvent:(nullable UIEvent *)event{
    NSLog(@"touchesMoved");
    self.shouldCreateNewTicket = NO;
}

- (void)touchesEnded:(NSSet *)touches withEvent:(nullable UIEvent *)event{
    NSLog(@"touchesEnded");
}

- (void)touchesCancelled:(nullable NSSet *)touches withEvent:(nullable UIEvent *)event{
    NSLog(@"touchesCancelled");

    [self createNewTicket];
}

- (void)createNewTicket{
    if(self.shouldCreateNewTicket){
        NSLog(@"Autorisé à créer un nouveau ticket");
        // Indique que le clic est sur la zone vide.
        if([self.mapboxDelegate respondsToSelector:@selector(mapboxViewDidCreateNewTicket:)]){
            [self.mapboxDelegate mapboxViewDidCreateNewTicket:self];
        }
    }
    else{
        NSLog(@"Pas autorisé à créer un nouveau ticket");
        // Indique que le clic est sur le marqueur d'annotation.
        self.shouldCreateNewTicket = YES;
    }
}

EDCMapboxViewController.m

- (void)viewDidLoad {
    [super viewDidLoad];
    self.mapView.shouldCreateNewTicket = YES;   
    .....
    .......
    ........
}

- (BOOL)mapView:(MGLMapView *)mapView annotationCanShowCallout:(id )annotation {
    NSLog(@"annotationCanShowCallout");

    // Indique que l'annotation est cliquée, alors ne permet pas de créer de ticket.
    self.mapView.shouldCreateNewTicket = NO;

    return YES;
}

- (void)mapboxViewDidCreateNewTicket:(MGLMapView*)mapView{
   // Indique que le clic est sur la zone vide et non sur le marqueur, puis autorise la création du ticket. 
}

Cela a fonctionné pour moi, j'espère que cela vous aidera aussi. Merci.

0voto

Gintas_ Points 2124

Voici comment j'ai résolu le problème, vous devriez comprendre le concept.

func onMapSingleTapped(recognizer: UITapGestureRecognizer)
{
    let viewLocation: CGPoint = recognizer.locationInView(map)

    // vérifier si des annotations ont été touchées
    if(map.annotations != nil)
    {
        for annotation in map.annotations!
        {
            if(annotation.isKindOfClass(MapCheckInAnnotation))
            {
                let pin: MapCheckInAnnotation = annotation as! MapCheckInAnnotation

                if let pinView = pin.view
                {
                    print("pinview \(pinView.frame.origin)")

                    // vérifier si le pin a été touché au lieu de juste la carte
                    if(viewLocation.x >= pinView.frame.origin.x && viewLocation.x < pinView.frame.origin.x + pinView.frame.width)
                    {
                        if(viewLocation.y >= pinView.frame.origin.y && viewLocation.y < pinView.frame.origin.y + pinView.frame.height)
                        {
                            mapView(map, didSelectAnnotationView: pinView)
                            return
                        }
                    }
                }
            }
        }
    }

    // non, aucune annotation n'a été cliquée
    let mapLocation: CLLocationCoordinate2D = map.convertPoint(viewLocation, toCoordinateFromView: map)

    print("onMapSingleTapped \(mapLocation)")

}

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