【发布时间】:2020-05-31 14:30:46
【问题描述】:
我正在尝试使用 CoreAnimation 为填充的矩形设置动画。给CAShapeLayer添加动画的时候,添加了动画,但是动画看起来很奇怪。
我已附上 gif:
我创建了一个小例子:
import Foundation
import UIKit
class TestView : UIView
{
private var progressLayer = CAShapeLayer()
override init(frame: CGRect)
{
super.init(frame: frame)
self.commonInit()
}
required init?(coder: NSCoder)
{
super.init(coder: coder)
self.commonInit()
}
override func layoutSubviews()
{
super.layoutSubviews()
self.commonInit()
}
fileprivate func commonInit()
{
self.progressLayer.removeFromSuperlayer()
let barWidth: CGFloat = self.frame.width * 0.33
let path = UIBezierPath(roundedRect: CGRect(x: self.bounds.width / 2 - barWidth / 2.0, y: self.bounds.height - 1.0, width: barWidth, height: 1.0), byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 6.0, height: 6.0))
self.progressLayer.path = path.cgPath
self.progressLayer.fillColor = UIColor.systemBlue.cgColor
self.progressLayer.strokeColor = UIColor.clear.cgColor
Swift.print(self.progressLayer.position)
self.progressLayer.position = CGPoint(x: -barWidth / 2.0, y: 0.0)
self.layer.addSublayer(self.progressLayer)
}
func animate()
{
let barWidth: CGFloat = self.frame.width * 0.33
let from = UIBezierPath(roundedRect: CGRect(x: self.bounds.width / 2 - barWidth / 2.0, y: self.bounds.height - 1.0, width: barWidth, height: 1.0), byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 6.0, height: 6.0))
let to = UIBezierPath(roundedRect: CGRect(x: self.bounds.width / 2 - barWidth / 2.0, y: 0.0, width: barWidth, height: self.bounds.height), byRoundingCorners: [.topLeft, .topRight], cornerRadii: CGSize(width: 6.0, height: 6.0))
// This works fine.
// let from = UIBezierPath(rect: CGRect(x: self.bounds.width / 2 - barWidth / 2.0, y: self.bounds.height - 1.0, width: barWidth, height: 1.0))
// let to = UIBezierPath(rect: CGRect(x: self.bounds.width / 2 - barWidth / 2.0, y: 0.0, width: barWidth, height: self.bounds.height))
let animation = CABasicAnimation(keyPath: "path")
animation.fromValue = from.cgPath
animation.toValue = to.cgPath
animation.duration = 0.8
animation.timingFunction = CAMediaTimingFunction(name: .easeInEaseOut)
animation.fillMode = .forwards
animation.isRemovedOnCompletion = false
self.progressLayer.add(animation, forKey: "path")
}
}
去除圆角时,一切正常。如何修复动画,使其仅在一维(从下到上)进行动画处理?
【问题讨论】:
-
动画化 CGPath 总是有风险的。您不知道 Cocoa 认为描绘一条路径变成另一条路径的方式(正如您的示例清楚地表明的那样)。将自己限制在动画边界和/或中心和/或变换上,您将能够实现可预测的效果。因此,如果目标是让条形图从下向上上升,则将整个条形本身从下向上移动。
标签: swift core-animation