Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

(Swift) UIPanGestureRecognizer works fine on view until subview is added to it

I have the following view (which is a subview of the overall view controller):

lazy var superView: UIView = {
    let cv = UIView()

    cv.backgroundColor = .gray
    cv.translatesAutoresizingMaskIntoConstraints = false
    cv.layer.cornerRadius = 5     
    cv.layer.masksToBounds = true     
    cv.isUserInteractionEnabled = true
    cv.addGestureRecognizer(UIPanGestureRecognizer(target: self, action: #selector(handlePan)))

    return cv
}()

and here is where I set my constraints for it:

// constraints for super view
func setupSuperView() {
    superView.centerXAnchor.constraint(equalTo: view.centerXAnchor).isActive = true
    superView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true

    superView.widthAnchor.constraint(equalTo: view.widthAnchor, constant: -24).isActive = true
    superView.heightAnchor.constraint(equalTo: view.heightAnchor, constant: -200).isActive = true

    // ISSUE: For some reason, adding this subview with or without constraints screws up the pan functionality of the superview
    superView.addSubview(subView)
}

this is the subview I add to be inside of the superView (which I am treating as a container view):

lazy var subview: UIImageView = {
    let sv = UIImageView()

    sv.translatesAutoresizingMaskIntoConstraints = false
    sv.contentMode = .scaleAspectFill        

    return sv
}()

And its constraints:

// constraints for yes/no view within superview
func setupSubView() {
    subView.centerXAnchor.constraint(equalTo: superView.centerXAnchor).isActive = true
    subView.centerYAnchor.constraint(equalTo: superView.centerYAnchor).isActive = true
}

Finally, here is where I establish the functionality for the pan gesture:

 // pan functionality for swiping on superview
func handlePan(gesture: UIPanGestureRecognizer) {

    guard let superview = gesture.view else {
        return
    }

    // point you are tapped on
    let point = gesture.translation(in: view)

    // reference for how far left or right of the center of the superview your pan is
    let xFromCenter = superview.center.x - view.center.x

    // allows the superview to move with your finger
    superview.center = CGPoint(x: view.center.x + point.x, y: view.center.y + point.y)

    // dragged right
    if xFromCenter > 0 {
        subView.image = #imageLiteral(resourceName: "yes")
        subView.tintColor = UIColor.green

    // else dragged left
    } else {
        subView.image = #imageLiteral(resourceName: "no")
        subView.tintColor = UIColor.red
    }

    // when you let go
    if gesture.state == UIGestureRecognizerState.ended {
        // animate superview back to center where it originally was
        UIView.animate(withDuration: 0.2) {

            superview.center = self.view.center
        }
    }

}

Before I added the subview (and when I comment it out) the pan gesture works perfectly fine on the superview. However, when I constrain the subview to be in the center of the superview and try moving the superview around the view controller, it acts bizarrely (only moving to the left properly, constantly jerking back to the center when moving to the right).

Any and all help is greatly appreciated.

like image 645
evanhaus Avatar asked Nov 08 '22 17:11

evanhaus


1 Answers

disable userinteraction on your subview and it will work i think!

You code for that should be like,

  subView.isUserInteractionEnabled = false
like image 59
Ketan Parmar Avatar answered Nov 14 '22 23:11

Ketan Parmar