Why is double tap still being picked up in this IOS code?

此生再无相见时 提交于 2019-12-11 11:37:42

问题


Background - I have a map (MapKit) with a callout (custom view added to an annotation view) - I have managed to ensure that the "long press" gesture made over the callout view does not get picked up (see below, using "shouldReceiveTouch")

Issue What I can't do is do the same thing (i.e. ignore) a double-click over the callout view, in that the MapKit map still somehow picks this up and zooms in. I've tried putting the Double Tap gesture in to trap it however it doesn't seem to be working.

Mapkit View Delegate Code

Setup of Gesture Recognisers

// Gesture Recogniser (Long Press)
let longPressGR = UILongPressGestureRecognizer(target: self, action: "longPressAction:")
longPressGR.minimumPressDuration = 1
longPressGR.delegate = self
self.mapView.addGestureRecognizer(longPressGR)

// Gesture Recogniser (Double Tap)
let doubleTapGR = UITapGestureRecognizer(target: self, action: "doubleTapAction:")
doubleTapGR.numberOfTapsRequired = 2
doubleTapGR.delegate = self
self.mapView.addGestureRecognizer(doubleTapGR)

Implement the "shouldReceiveTouch" for UIGestureRecognizerDelegate

extension GCMapViewHelper : UIGestureRecognizerDelegate {
 func gestureRecognizer(gestureRecognizer: UIGestureRecognizer, shouldReceiveTouch touch: UITouch) -> Bool {
    guard let touchesView = touch.view else { fatalError("ERROR: Touch event received was nil") }

    for annotation in self.mapView.selectedAnnotations {
        if annotation is GCAnnotation {
            let annotationView = self.mapView.viewForAnnotation(annotation)
            if let annotationView = annotationView {
                if (touchesView.isDescendantOfView(annotationView)) {
                    return false
                }
            }
        }
    }
    return true
 }
}

EDIT: It seems the issue is the double-tap gesture recognizer is NOT picking up the double tap...any ideas? i.e. this is not working..

doubleTapGR.numberOfTapsRequired = 2

EDIT 2 Here is a simplified view of the issue re code example:

With the code below in terms of what I see in the console output from print statements: * "longPressAction" - This appears/works * "tapAction" - This does NOT appear, even when I double tap over the MKMapView. So this is my isssue here.

import UIKit
import MapKit

class ViewController: UIViewController {

    @IBOutlet weak var mapview: MKMapView!

    func longPressAction() {
        print("longPressAction")
    }

    func tapAction() {
        print("tapAction")  // ** Not appearing in console ** 
    }

    override func viewDidLoad() {
        super.viewDidLoad()

        // Gesture Recogniser (Long Press)
        let longPressGR = UILongPressGestureRecognizer(target: self, action: "longPressAction")
        longPressGR.minimumPressDuration = 1
        self.mapview.addGestureRecognizer(longPressGR)

        let tapGR = UITapGestureRecognizer(target: self, action: "tapAction")
        tapGR.numberOfTapsRequired = 2
        self.mapview.addGestureRecognizer(tapGR)

        //tapGR.requireGestureRecognizerToFail(longPressGR)

    }

}

回答1:


While it's not a direct answer to your question - I have a workaround for you.

If you add your gesture recognizers to your custom annotation view then you can capture both long press and double tap over the annotation view and any associated callout.

Some example code I wrote to try this:

import UIKit
import MapKit

class StarAnnotation : NSObject, MKAnnotation {
    let title: String?
    let coordinate: CLLocationCoordinate2D

    init(title: String, coordinate: CLLocationCoordinate2D) {
        self.title = title
        self.coordinate = coordinate
        super.init()
    }
}

class StarAnnotationView : MKAnnotationView, UIGestureRecognizerDelegate {
    override init(annotation: MKAnnotation?, reuseIdentifier: String?) {
        super.init(annotation: annotation, reuseIdentifier: reuseIdentifier)
        self.image = UIImage(named: "star")

        // Gesture Recogniser (Long Press)
        let longPressGR = UILongPressGestureRecognizer(target: self, action: "longPressAction:")
        longPressGR.minimumPressDuration = 1
        longPressGR.delegate = self
        self.addGestureRecognizer(longPressGR)

        // Gesture Recogniser (Double Tap)
        let doubleTapGR = UITapGestureRecognizer(target: self, action: "doubleTapAction:")
        doubleTapGR.numberOfTapsRequired = 2
        doubleTapGR.delegate = self
        self.addGestureRecognizer(doubleTapGR)

    }

    override init(frame: CGRect) {
        super.init(frame: frame)
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    func doubleTapAction(recognizer: UITapGestureRecognizer) {
        if recognizer.numberOfTapsRequired == 2 {
            print("double tapped")
        }
    }

    func longPressAction(recognizer: UILongPressGestureRecognizer) {
        print("long pressed")
    }
}

class ViewController: UIViewController, MKMapViewDelegate {

    @IBOutlet weak var mapView: MKMapView!

    override func viewDidLoad() {
        super.viewDidLoad()

        // set up map view and sample annotation
        let operaHouseCoord = CLLocationCoordinate2D(latitude: -33.8587, longitude: 151.2148)
        let span = MKCoordinateSpan(latitudeDelta: 0.01, longitudeDelta: 0.01)
        let operaHouseAnnotation = StarAnnotation(title: "Opera House", coordinate: operaHouseCoord)
        mapView.region = MKCoordinateRegion(center: operaHouseCoord, span: span)
        mapView.delegate = self
        mapView.addAnnotation(operaHouseAnnotation)
    }

    func mapView(mapView: MKMapView, viewForAnnotation annotation: MKAnnotation) -> MKAnnotationView? {
        if let annotation = annotation as? StarAnnotation {
            let identifier = "star"
            if let dequeuedView = mapView.dequeueReusableAnnotationViewWithIdentifier(identifier) as? StarAnnotationView {
                dequeuedView.annotation = annotation
                return dequeuedView
            } else {
                let view = StarAnnotationView(annotation: annotation, reuseIdentifier: identifier)
                view.canShowCallout = true
                return view
            }
        }
        return nil
    }
}


来源:https://stackoverflow.com/questions/35697397/why-is-double-tap-still-being-picked-up-in-this-ios-code

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!