UIPanGestureRecognizer
で指が離されたときのvelocity
を使って曲線移動するのアニメーションを作ります。
Swift 4.2
import UIKit
class ViewController: UIViewController {
var animationSample: AnimationSample?
override func viewDidLoad() {
super.viewDidLoad()
animationSample = AnimationSample(view: view)
}
}
class AnimationSample {
let view: UIView
let circle: UIView = {
let diameter: CGFloat = 120
let view = UIView(frame: CGRect(
x: 0,
y: 0,
width: diameter,
height: diameter))
view.layer.cornerRadius = diameter * 0.5
view.backgroundColor = .blue
return view
}()
init(view: UIView) {
self.view = view
view.addSubview(circle)
circle.center = view.center
let pan = UIPanGestureRecognizer(
target: self,
action: #selector(didPan(gesture:)))
circle.addGestureRecognizer(pan)
}
@objc private func didPan(gesture: UIPanGestureRecognizer) {
let location = gesture.location(in: nil)
switch gesture.state {
case .began:
circle.layer.removeAnimation(forKey: "animation")
UIView.animate(withDuration: 0.1) {
self.circle.center = location
}
case .changed:
circle.center = location
case .ended, .failed, .cancelled:
circle.center = location
animate(velocity: gesture.velocity(in: nil))
break
case .possible:
break
}
}
func animate(velocity: CGPoint) {
let speed: CGFloat = 0.5
let startPoint = circle.center
let endPoint = view.center
let controlPoint = CGPoint(
x: startPoint.x + velocity.x * speed,
y: startPoint.y + velocity.y * speed)
let animation = CAKeyframeAnimation(keyPath: "position")
let path = CGMutablePath()
path.move(to: startPoint)
path.addQuadCurve(to: endPoint, control: controlPoint)
animation.path = path
animation.duration = 1.0
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false
CATransaction.begin()
CATransaction.setCompletionBlock {
self.circle.center = endPoint
}
circle.layer.add(animation, forKey: "animation")
CATransaction.commit()
}
}