UIView 在沿 UIBezierPath 的动画期间暂停
UIView pauses during animation along UIBezierPath
我正在尝试使用 CAKeyframeAnimation 为 UIView(正方形)设置动画以沿 UIBezierPath 移动。正方形在贝塞尔曲线路径的两个点处暂停,两个点都在路径开始之前 arc.This 是我的 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。关于为什么会发生这种情况以及如何解决这个问题的任何想法?
您使用的路径由 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)
我正在尝试使用 CAKeyframeAnimation 为 UIView(正方形)设置动画以沿 UIBezierPath 移动。正方形在贝塞尔曲线路径的两个点处暂停,两个点都在路径开始之前 arc.This 是我的 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。关于为什么会发生这种情况以及如何解决这个问题的任何想法?
您使用的路径由 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)