Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

how can I detect if singleTap was tapped or annotation on mapView of mapbox?

Requirment on iOS for mapBox map. (I am not talking about MKMapView) how can we detect if singleTap was tapped or annotation on mapView? I need that singleTap will be handled only on empty area of map (without pins), and didSelectAnnotation called when i tap on pin.

But I found on android we have method like this

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

and along with that

mapboxMap.setInfoWindowAdapter(new MapboxMap.InfoWindowAdapter() { ... }) will display the annotation.

Don't we have same kind of concept in iOS ?

The actual problem is in iOS is, when I add singleTapGesture on mapView of Mapbox

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

the delegate method of mapView of mapbox will not call.

- (nullable UIView <MGLCalloutView> *)mapView:(MGLMapView *)mapView calloutViewForAnnotation:(id <MGLAnnotation>)annotation;

to make sure the delegate method must call, then I dont have to use singleTapGesture

Here the situation is either this or that, but as per me need I needed both.

Looking forward of any solution. Thanks,

like image 563
Nasir Avatar asked Jun 28 '16 07:06

Nasir


2 Answers

Subclass MGLMapView and delegate its' touchesEnded.

protocol MapViewTapDelegate: class {

    func mapViewTapped(withTouchLocation touchLocation: CLLocationCoordinate2D)
}

class MapView: MGLMapView {

    weak var tapDelegate: MapViewTapDelegate?

    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        super.touchesEnded(touches, with: event)

        guard let touch = touches.first else { return }

        let touchLocation = convert(touch.location(in: self), toCoordinateFrom: nil)

        tapDelegate?.mapViewTapped(withTouchLocation: touchLocation)
    }

}

As touchesEnded isn't triggered when didSelect annotation is called and vice versa, this is what you need.

class ViewController: UIViewController {
    @IBOutlet weak var mapView: MapView! {

        didSet {

            mapView.delegate = self; mapView.tapDelegate = self
        }
    }

}

extension ViewController: MGLMapViewDelegate {

    func mapView(_ mapView: MGLMapView, didSelect annotation: MGLAnnotation) {

        print("didSelect annotationWithCoordinate: \(annotation.coordinate)")
    }

}

extension ViewController: MapViewTapDelegate {

    func mapViewTapped(withTouchLocation touchLocation: CLLocationCoordinate2D) {

        print("mapViewTapped touchLocation: \(touchLocation)")
    }

}
like image 154
IT Gypsy Avatar answered Sep 28 '22 13:09

IT Gypsy


I think that the method -(void)mapView:(MGLMapView *)mapView didSelectAnnotation:(id<MGLAnnotation>)annotation will solve your problem for selecting annotation.

like image 30
Stefan Avatar answered Sep 28 '22 13:09

Stefan