surToTheW
surToTheW

Reputation: 832

View moves weirdly on rotation through pan gesture

I have a pan gesture on a button that moves the button in the direction of the pan. When the translation is "far enough" the button gets rotated. On this rotation the button visible goes to its initial position or close and then back where it should be. Cannot figure out what is going on. This is my code:

    @IBAction func didPanButton(_ sender: UIPanGestureRecognizer) {

    print("Did pan button", sender.translation(in: sender.view).x)

    answerButton.center.x = view.center.x + sender.translation(in: sender.view).x

    switch buttonPosition {
    case .left:
        print("Rotate button left")
        UIView.animate(withDuration: 0.5, animations: {
            self.rotateButtonLeft()
        })
    case .right:
        print("Rotate button right")
        UIView.animate(withDuration: 0.5, animations: {
            self.rotateButtonRight()
        })
    case .middle:
        print("Remove button rotation")
        UIView.animate(withDuration: 0.5, animations: {
            self.removeButtonRotation()
        })
    }

} 

var buttonPosition : ButtonPosition {
    let leftWidth = (view.frame.size.width - answerButton.frame.size.width) / 2

    if answerButton.frame.origin.x < leftWidth / 2 {
        return .left
    }

    if answerButton.frame.origin.x > leftWidth * 3 / 2 {
        return .right
    }

    return .middle
}

func rotateButtonLeft() {
    let degrees : CGFloat = -10; //the value in degrees
    answerButton.transform = CGAffineTransform(rotationAngle: degrees * CGFloat.pi/180);
    let image = UIImage(named: "item_no")
    answerButton.setImage(image, for: UIControlState.normal)
}

func rotateButtonRight() {
    let degrees : CGFloat = 10; //the value in degrees
    answerButton.transform = CGAffineTransform(rotationAngle: degrees * CGFloat.pi/180);
    let image = UIImage(named: "item_yes")
    answerButton.setImage(image, for: UIControlState.normal)
}

func removeButtonRotation() {
    let degrees : CGFloat = 0; //the value in degrees
    answerButton.transform = CGAffineTransform(rotationAngle: degrees * CGFloat.pi/180);
    let image = UIImage(named: "item_neutral")
    answerButton.setImage(image, for: UIControlState.normal)
}

Upvotes: 1

Views: 191

Answers (1)

rob mayoff
rob mayoff

Reputation: 385590

Your button has constraints to set its position. When auto layout runs, it resets the button's center according to those constraints. Setting the button's image is triggering auto layout.

You have three options to fix this:

  1. Change the button's position by updating the constraints, OR
  2. Change the button's position by setting its transform instead of by changing its center, OR
  3. Don't use constraints to position the button.

Upvotes: 2

Related Questions