Skip to content

Instantly share code, notes, and snippets.

@dev-yong
Created May 14, 2020 07:37
Show Gist options
  • Save dev-yong/eb33e2d79f154abdf2f20d02c39606e6 to your computer and use it in GitHub Desktop.
Save dev-yong/eb33e2d79f154abdf2f20d02c39606e6 to your computer and use it in GitHub Desktop.
class ViewController: UIViewController {
let targetView = UIView(frame: .init(x: 50, y: 150, width: 50, height: 50))
let slider = UISlider(frame: .init(x: 0, y: 100, width: 300, height: 30))
var animator: UIViewPropertyAnimator?
var displayLink: CADisplayLink?
var token: NSKeyValueObservation?
override func loadView() {
super.loadView()
self.targetView.backgroundColor = .orange
self.view.addSubview(self.targetView)
self.view.addSubview(self.slider)
}
override func viewDidLoad() {
super.viewDidLoad()
self.slider.addTarget(self, action: #selector(self.valueChanged(_:)), for: .valueChanged)
self.targetView.addGestureRecognizer(UITapGestureRecognizer(target: self, action: #selector(self.tapped(_:))))
self.setUpAnimator()
self.setUpDisplayLink()
}
func setUpDisplayLink() {
self.displayLink = CADisplayLink(target: self, selector: #selector(displaying(_:)))
self.displayLink?.add(to: .main, forMode: .common)
self.displayLink?.isPaused = true
}
func setUpAnimator() {
let timing = UICubicTimingParameters(animationCurve: .easeOut)
self.animator = UIViewPropertyAnimator(duration: 2.0, timingParameters: timing)
self.animator?.addAnimations {
self.targetView.center.x = 300
self.targetView.transform = .init(rotationAngle: CGFloat(Double.pi / 2))
}
self.animator?.pausesOnCompletion = true
// It will never be called.
// because pausesOnCompletion is true
self.animator?.addCompletion { _ in
self.targetView.backgroundColor = .blue
}
self.token = self.animator?.observe(\.isRunning, changeHandler: { (animator, changed) in
self.displayLink?.isPaused = !animator.isRunning
})
}
@objc func displaying(_ sender: CADisplayLink) {
self.slider.value = Float(self.animator?.fractionComplete ?? 0)
}
@objc func valueChanged(_ slider: UISlider) {
guard let animator = self.animator else { return }
animator.pauseAnimation()
animator.fractionComplete = CGFloat(slider.value)
}
@objc func tapped(_ sender: UITapGestureRecognizer) {
guard let animator = self.animator else { return }
if animator.isRunning {
animator.pauseAnimation()
} else {
animator.startAnimation()
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment