我尝试使用CAKeyframeAnimation动画UIView(正方形)以沿UIBezierPath移动。方块在贝塞尔路径的两个点处暂停,两个点都在路径开始弧之前。这是我的UIBezierPath和动画的代码:
func createTrack() -> UIBezierPath {
let path = UIBezierPath()
path.move(to: CGPoint(x: layerView.frame.size.width/2, y: 0.0))
path.addLine(to: CGPoint(x: layerView.frame.size.width - 100.0, y: 0.0))
path.addArc(withCenter: CGPoint(x: layerView.frame.size.width - 100.0,y: layerView.frame.height/2), radius: layerView.frame.size.height/2, startAngle: CGFloat(270).toRadians(), endAngle: CGFloat(90).toRadians(), clockwise: true)
path.addLine(to: CGPoint(x: 100.0, y: layerView.frame.size.height))
path.addArc(withCenter: CGPoint(x: 100.0,y: layerView.frame.height/2), radius: layerView.frame.size.height/2, startAngle: CGFloat(90).toRadians(), endAngle: CGFloat(270).toRadians(), clockwise: true)
path.close()
return path
}
@IBAction func onAnimatePath(_ sender: Any) {
let square = UIView()
square.frame = CGRect(x: 55, y: 300, width: 20, height: 20)
square.backgroundColor = UIColor.red
layerView.addSubview(square)
let animation = CAKeyframeAnimation(keyPath: "position")
animation.path = trackPath.cgPath
animation.rotationMode = kCAAnimationRotateAuto
animation.repeatCount = Float.infinity
animation.duration = 60
square.layer.add(animation, forKey: "animate position along path")
}
layerView只是一个UIView。关于为什么会发生这种情况以及如何解决这个问题的想法?
答案 0 :(得分:2)
您使用的路径包含5个段(两个弧和三个线(包括关闭路径时的一个)),并且动画在每个段上花费相同的时间。如果此路径太窄,这些线段将没有长度,并且方块将在每个线段中显示12秒。
您可能希望使用"paced" calculation mode来获得恒定速度
animation.calculationMode = kCAAnimationPaced
这样,红色方块将以恒定的速度移动 - 无论形状的每个部分有多长。
仅此一项就可以为您提供所需的结果,但您可以采取更多措施来简化路径。
addArc(...)
方法相当智能,并且会从当前点添加一条直线到弧的起点,因此不需要两条显式线。
此外,如果您更改初始点,您将路径移动到具有与第二个弧的中心相同的x
分量,则路径将自行关闭。在这里,你需要的只是两个弧。
也就是说,如果您要创建的形状是这样的圆角矩形,那么您可以使用UIBezierPath(roundedRect:cornerRadius:)
便利初始值设定项:
let radius = min(layerView.bounds.width, layerView.bounds.height) / 2.0
let path = UIBezierPath(roundedRect: layerView.bounds, cornerRadius: radius)