You are seeing the jump because the blueView already has the rotation transform set when you animate the translation transform. That leads to unexpected results.
To make it work you combine the rotation and translation transform before the animation and then reset the transform animated:
To translate the blue view 100pt up and rotate it back to normal you do this:
- Add a transform to the
blueView that translates it 100pt down and rotates it 45°
- Set the centerYAnchor constant to -100 to have the blueView in the correct position before the animation.
- Animate the
blueView.transform = .identity to remove the transform animated
This is a working example:
class ViewController: UIViewController {
let blueView = UIView()
override func viewDidLoad() {
super.viewDidLoad()
blueView.backgroundColor = .blue
view.addSubview(blueView)
blueView.transform = CGAffineTransform(translationX: 0, y: 100).rotated(by: -CGFloat.pi / 4)
let button = UIButton(type: .custom)
button.setTitle("Animate", for: .normal)
button.setTitleColor(.blue, for: .normal)
button.addTarget(self, action: #selector(didPress), for: .touchUpInside)
view.addSubview(button)
blueView.translatesAutoresizingMaskIntoConstraints = false
button.translatesAutoresizingMaskIntoConstraints = false
NSLayoutConstraint.activate([
blueView.widthAnchor.constraint(equalToConstant: 20),
blueView.heightAnchor.constraint(equalToConstant: 20),
blueView.centerXAnchor.constraint(equalTo: view.centerXAnchor),
blueView.centerYAnchor.constraint(equalTo: view.centerYAnchor, constant: -100),
button.centerXAnchor.constraint(equalTo: view.centerXAnchor),
button.bottomAnchor.constraint(equalTo: view.safeAreaLayoutGuide.bottomAnchor, constant: -40)
])
}
@objc func didPress(sender: UIButton) {
UIView.animate(withDuration: 0.5, animations: {
self.blueView.transform = .identity
})
}
}