ios - CAAnimation 为复选标记绘图设置动画

标签 ios swift animation core-animation

我正在尝试制作一个简单的复选标记控件,其中仅包含一个正方形和一个复选标记。我想在点击控件时为复选标记的绘制和删除设置动画。这是我目前所拥有的:

let path = UIBezierPath()
path.move(to: CGPoint(x: 0, y: checkBox.size * 2 / 3))
path.addLine(to: CGPoint(x: checkBox.size / 3, y: checkBox.size))
path.addLine(to: CGPoint(x: checkBox.size, y: 0))

pathLayer.frame = checkBox.bounds
pathLayer.path = path.cgPath
pathLayer.strokeColor = UIColor.red().cgColor
pathLayer.fillColor = nil
pathLayer.lineWidth = checkMarkWidth
pathLayer.lineJoin = kCALineJoinBevel

let pathAnimation = CABasicAnimation(keyPath:"strokeEnd")
pathAnimation.duration = checkMarkAnimationDuration
pathAnimation.fromValue = NSNumber(floatLiteral: 0)
pathAnimation.toValue = NSNumber(floatLiteral: 1)

let reverseAnimation = CABasicAnimation(keyPath:"strokeEnd")
reverseAnimation.duration = checkMarkAnimationDuration
reverseAnimation.fromValue = NSNumber(floatLiteral: 1)
reverseAnimation.toValue = NSNumber(floatLiteral: 0)
reverseAnimation.delegate = self

然后我开始这样的动画:

var on: Bool = false {
    didSet {
        if on {
            checkBox.layer.addSublayer(pathLayer)
            pathLayer.removeAllAnimations()
            pathLayer.add(pathAnimation, forKey:"strokeEnd")
        } else {
            pathLayer.removeAllAnimations()
            pathLayer.add(reverseAnimation, forKey:"strokeEnd")
        }
    }
}

最后在我的 CAAnimationDelegate 中我这样做了:

public func animationDidStop(_ anim: CAAnimation, finished flag: Bool) {
    pathLayer.removeFromSuperlayer()
}

这看起来不错,除了当我在真实设备上测试它时,当反向动画完成时,但在图层被移除之前,会有一点闪光。看来我缺少一个 animationWillStop 回调。

enter image description here

有什么办法可以解决这个问题吗?

也欢迎任何其他关于如何改进此代码的建议,因为我是 Core Animation 的新手。

最佳答案

Core Animation 有三层树,一层是模型层树,你最常与之交互。一个是表示层树,它包含飞行中运行的动画值。最后一个是render layer tree,它实际上是渲染层并且是Core Animation私有(private)的。

CAAnimation 只改变 CALayer 的 presentationLayer 的值。动画结束后,动画被移除并且 strokeEnd 跳回到到你的模态层的值:1.0。这就是为什么你有闪光灯。

所以,你可以改变

var on: Bool = false {
    didSet {
        if on {
            checkBox.layer.addSublayer(pathLayer)
            pathLayer.removeAllAnimations()
            pathLayer.add(pathAnimation, forKey:"strokeEnd")
        } else {
            pathLayer.removeAllAnimations()
            pathLayer.add(reverseAnimation, forKey:"strokeEnd")
        }
    }
}

var on: Bool = false {
    didSet {
        if on {
            checkBox.layer.addSublayer(pathLayer)
            pathLayer.strokeEnd = 1.0 // set property to final state
            pathLayer.removeAllAnimations()
            pathLayer.add(pathAnimation, forKey:"strokeEnd")
        } else {
            pathLayer.strokeEnd = 0.0 // set property to final state
            pathLayer.removeAllAnimations()
            pathLayer.add(reverseAnimation, forKey:"strokeEnd")
        }
    }
}

关于ios - CAAnimation 为复选标记绘图设置动画,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/38351858/

相关文章:

ios - 如何在 ios 中的 tableview 上方添加按钮

ios - ios 和 mongodb 的时间戳选择,moment.js

iphone - 代码 : I have made a UISwitch and it works fine but then when I switch a view and come back it is playing up

ios - 在 App 开始时在 iOS 中获取位置

javascript - 如何使用 slider 更改 anime.js 事件的速度(持续时间)?

css - 使用平滑结果动画 CSS 背景位置(子像素动画)

ios - 在对象类型(自定义)xcode 上找不到属性

swift - 状态栏下出现意外填充

swift - 将字符串转换为日期会分配错误的值

jQuery GIF 动画