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

2

6

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.

Blamable answered 6/9, 2017 at 6:11 Comment(5)
Try adding panGesture to the superView below superView.addSubview(subView) functionChromo
Do you mean that once you add subview your pan gesture stop working ?Storm
@Lion Correct, once I add my subView to the superView the pan gesture stops working correctly.Blamable
If you are adding uiview or uiimageview as subview than set it's user interaction to false and it will work i thinkStorm
@AravindAR Tried that, unfortunately still getting the same issue.Blamable
B
0

I figured out the issue. While I don't know the reason why this is the fix, the issue lies in the fact that the image I was using for the "no" option of panning the container view left was causing the entire view to act bizarrely because it is a different image.

I tested this out by making both options "yes" despite whether you pan the view left or right. This fixed the issue which led me to believe that the problem was the image being switched depending on whether you swipe left or right. I don't know why it has an issue with displaying two different images but I will try to figure that out as well.

Thank you for all of the helpful input!

Blamable answered 10/9, 2017 at 5:26 Comment(0)
S
2

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

You code for that should be like,

  subView.isUserInteractionEnabled = false
Storm answered 6/9, 2017 at 9:20 Comment(1)
I tried this and I am still getting the same issue unfortunately.Blamable
B
0

I figured out the issue. While I don't know the reason why this is the fix, the issue lies in the fact that the image I was using for the "no" option of panning the container view left was causing the entire view to act bizarrely because it is a different image.

I tested this out by making both options "yes" despite whether you pan the view left or right. This fixed the issue which led me to believe that the problem was the image being switched depending on whether you swipe left or right. I don't know why it has an issue with displaying two different images but I will try to figure that out as well.

Thank you for all of the helpful input!

Blamable answered 10/9, 2017 at 5:26 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.