【问题标题】:UIView pauses during animation along UIBezierPathUIView 在沿 UIBezierPath 的动画期间暂停
【发布时间】:2018-06-19 02:59:00
【问题描述】:

我正在尝试使用 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。关于为什么会发生这种情况以及如何解决这个问题的任何想法?

【问题讨论】:

标签: ios swift animation uiview core-animation


【解决方案1】:

您使用的路径由 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)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多