我在进步圈中遇到奇怪的视觉怪癖。我希望绿色圆圈(CAShapeLayer)能够以五分之一的增量平滑地进行动画制作。 0/5 =没有绿色圆圈。 5/5 =全绿色圆圈。问题是绿色圆圈在它应该的地方动画过去,然后突然收缩到适当的位置。按下加号和减号按钮时会发生这种情况。下面有一个gif演示正在发生的事情。
每个动画的持续时间应该持续0.25秒,并且应该平滑动画显示UP和DOWN(取决于是否按下加号或减号按钮)从动画最后结束的位置(目前不是发生的情况。)
在我的UIView中,我绘制圆圈,以及制作进度位置动画的方法:
class CircleView: UIView {
let progressCircle = CAShapeLayer()
required init?(coder aDecoder: NSCoder) {
super.init(coder: aDecoder)
}
override init(frame: CGRect) {
super.init(frame: frame)
}
override func draw(_ rect: CGRect) {
let circlePath = UIBezierPath(ovalIn: self.bounds)
progressCircle.path = circlePath.cgPath
progressCircle.strokeColor = UIColor.green.cgColor
progressCircle.fillColor = UIColor.red.cgColor
progressCircle.lineWidth = 10.0
// Add the circle to the view.
self.layer.addSublayer(progressCircle)
}
func animateCircle(circleToValue: CGFloat) {
let fifths:CGFloat = circleToValue / 5
let animation = CABasicAnimation(keyPath: "strokeEnd")
animation.duration = 0.25
animation.fromValue = fifths
animation.byValue = fifths
animation.fillMode = kCAFillModeBoth
animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
progressCircle.strokeEnd = fifths
// Create the animation.
progressCircle.add(animation, forKey: "strokeEnd")
}
}
在我的VC中:
我通过以下方式启动圆圈和起点:
let myDrawnCircle = CircleView()
var startingPointForCircle = CGFloat()
viewDidAppear:
startingPointForCircle = 0.0
myDrawnCircle.frame = CGRect(x: 100, y: 100, width: 150, height: 150)
myDrawnCircle.backgroundColor = UIColor.white
myDrawnCircle.animateCircle(circleToValue: startingPointForCircle)
self.view.addSubview(myDrawnCircle)
textLabel.text = "\(startingPointForCircle)"
制作炫酷动画的实际按钮:
@IBAction func minusButtonPressed(_ sender: UIButton) {
if startingPointForCircle > 0 {
startingPointForCircle -= 1
textLabel.text = "\(startingPointForCircle)"
myDrawnCircle.animateCircle(circleToValue: startingPointForCircle)
}
}
@IBAction func plusButtonPressed(_ sender: UIButton) {
if startingPointForCircle < 5 {
startingPointForCircle += 1
textLabel.text = "\(startingPointForCircle)"
myDrawnCircle.animateCircle(circleToValue: startingPointForCircle)
}
}
这里有一个gif,向您展示动态生动的动画。
如何让我的动画顺利地从适当的值中设置适当的值?
答案 0 :(得分:0)
我的猜测是它与使用密钥路径有关。我不知道如何使用键路径来修复它,但您可以使用自定义视图尝试不同的大头钉,并为传递给用于绘制弧的方法的值设置动画。
以下代码由PaintCode生成。为arc
传递的值指定了绘制圆弧的圆上的点。这用于自定义UIView的drawRect
方法。创建自定义视图的CGFloat属性,只需更改该值,然后在动画代码后调用视图上的setNeedsDisplay
。
func drawCircleProgress(frame frame: CGRect = CGRect(x: 0, y: 0, width: 40, height: 40), arc: CGFloat = 270) {
//// General Declarations
let context = UIGraphicsGetCurrentContext()
//// Color Declarations
let white = UIColor(red: 1.000, green: 1.000, blue: 1.000, alpha: 1.000)
let white50 = white.colorWithAlpha(0.5)
//// Oval Drawing
CGContextSaveGState(context)
CGContextTranslateCTM(context, frame.minX + 20, frame.minY + 20)
CGContextRotateCTM(context, -90 * CGFloat(M_PI) / 180)
let ovalRect = CGRect(x: -19.5, y: -19.5, width: 39, height: 39)
let ovalPath = UIBezierPath()
ovalPath.addArcWithCenter(CGPoint(x: ovalRect.midX, y: ovalRect.midY), radius: ovalRect.width / 2, startAngle: 0 * CGFloat(M_PI)/180, endAngle: -arc * CGFloat(M_PI)/180, clockwise: true)
white.setStroke()
ovalPath.lineWidth = 1
ovalPath.stroke()
CGContextRestoreGState(context)
}
答案 1 :(得分:0)
期望的结果就像在animateCircle方法中注释掉Value / byValue一样简单。这是由@dfri指出的 - “将fromValue和toValue都设置为nil然后:”在目标层的表示层中keyPath的先前值和目标层的表示层中keyPath的当前值之间进行插值。“
//animation.fromValue = fifths
//animation.byValue = fifths