Reputation: 2513
Please have a look at the following method which I am using to move a sublayer 50 points up along the y axis. In particular, pay attention to the last line (which is commented out).
@objc func animateButtonPressed(_ sender: UIButton) {
let initialValue = customView.sublayer.position.y
let finalValue = customView.sublayer.position.y - 50
let animation = CABasicAnimation(keyPath: "position.y")
animation.fromValue = initialValue
animation.toValue = finalValue
animation.duration = 2
customView.sublayer.add(animation, forKey: "Reposition")
//customView.sublayer.position.y = finalValue
}
With the code as shown, I get the following behavior:
Everything I read informs me that the "jumping back" occurs because I have not updated the model to reflect the final value. So, let's update the model by uncommenting the final line. Now the behavior is:
The jump is apparently occurring because the final position is being set on the model. I feel like I am in a catch 22. Any help will be much appreciated.
A working project that illustrates the problem can be found on GitHub
Xcode 10.0, iOS 12.2, Swift 4.2
Upvotes: 1
Views: 2967
Reputation: 535118
Here's the canonical form as developed and explained in my book. Set the animated layer to its final value beforehand but with implicit animation turned off, like this:
@objc func animateButtonPressed(_ sender: UIButton) {
let initialValue = customView.sublayer.position.y
let finalValue = customView.sublayer.position.y - 50
CATransaction.setDisableActions(true) // <-- *
customView.sublayer.position.y = finalValue // <-- *
let animation = CABasicAnimation(keyPath: "position.y")
animation.fromValue = initialValue
animation.toValue = finalValue
animation.duration = 2
customView.sublayer.add(animation, forKey: "Reposition")
}
Upvotes: 6