Search code examples
iosswiftuipangesturerecognizer

Strange issue with UIPanGestureRecognizer in Swift


I'm trying to add pan gesture to my view but I do not know why it does not want to work. Here is the code of my UIView:

    self.infoView = UIView()
    self.mapView.addSubview(infoView)
    infoView.backgroundColor = .white
    infoView.layer.cornerRadius = 10.0
    infoView.layer.masksToBounds = true
    infoView.isUserInteractionEnabled = true
    infoView.translatesAutoresizingMaskIntoConstraints = false

    let panGesture = UIPanGestureRecognizer(target: self, action: #selector(self.moveInfoView(recognizer:)))
    infoView.addGestureRecognizer(panGesture)

I'm defining it in my UIViewController as:

var infoView: UIView!

and my pan gesture method looks like:

@objc func moveInfoView(recognizer:UIPanGestureRecognizer) {
    let translation = recognizer.translation(in: self.view)
    if let view = recognizer.view {
        view.center = CGPoint(x:view.center.x + translation.x,
                              y:view.center.y + translation.y)
    }
    recognizer.setTranslation(CGPoint.zero, in: self.view)
}

I really cannot see my mistake. It seems everything is correct there but it seems I'm wrong. Could you please point to my mistake?

UPDATE

My constraints:

let constraints = [
        // InfoView constraints
        NSLayoutConstraint(item: infoView, attribute: .bottom, relatedBy: .equal, toItem: self.view.safeAreaLayoutGuide, attribute: .bottom, multiplier: 1.0, constant: 0.0),
        NSLayoutConstraint(item: infoView, attribute: .leading, relatedBy: .equal, toItem: self.view, attribute: .leading, multiplier: 1.0, constant: 0.0),
        NSLayoutConstraint(item: infoView, attribute: .trailing, relatedBy: .equal, toItem: self.view, attribute: .trailing, multiplier: 1.0, constant: 0.0),
        infoViewHeightConstraint]

where

let infoViewHeightConstraint = infoView.heightAnchor.constraint(greaterThanOrEqualToConstant: 112.0)

Solution

  • I suspect the problem is with your view being a subview of GMSMapView. The map view already has a bunch of gesture recognizers added to it and the gesture recognizer callbacks are sent to the GMSMapView instance and not your subview. Although there is a settings property on GMSMapView which lets you configure the user interface settings for the map. Try the following code to enable gestures:

    self.mapView.settings.consumesGesturesInView = false
    

    There are also other settings you could customize there. Hope this helps