首页 > 解决方案 > 快速绘制带有笔画动画的复选标记

问题描述

我的 iOS 应用程序中有一个按钮,我想在用户点击它时应用一个复选标记动画,但我不知道如何实现这一点。如果有人有想法,请帮助我。下面是我要创建的动画的示例 gif 图像。

在此处输入图像描述

标签: iosswiftcore-animation

解决方案


要创建该动画,您可以为蒙版设置动画,从左到右显示复选标记,正如马特所说,或者您可以使用 aCAShapeLayer来绘制复选标记,然后strokeEnd为形状图层的属性设置动画。

(滑动蒙版方法总是会从左到右显示视图的内容¹,无论视图包含复选标记还是小猫的图片。形状图层描边方法特定于使用UIBezierPath(或 Core Foundation 等效项CGPath)绘制形状,但是您可以使用它从头到尾绘制复杂的形状,甚至是循环返回的形状。它不仅限于始终从左到右显示视图内容。)

碰巧的是,您在问题中使用的图像是我上周末创建的使用该CAShapeLayer方法的演示应用程序的产品。

您可以在此处找到完整的演示应用程序:

https://github.com/DuncanMC/AnimateCheckMark.git

为了对笔画进行动画处理,您需要将复选标记创建为形状图层。创建复选标记的示例代码如下所示:

private func checkmarkPath() -> CGPath {
    let path = UIBezierPath()
    path.move(to: CGPoint(x: 5, y: bounds.midY))
    path.addLine(to: CGPoint(x: 25, y: bounds.midY + 20))
    path.addLine(to: CGPoint(x: 45, y: bounds.midY - 20))
    return path.cgPath
}

(该代码不是很通用。它创建了一个固定大小的复选标记。您可能需要修改它以缩放复选标记以适合它所属的视图。)

创建形状图层并在其中安装复选标记后,您需要创建一个动画来为形状图层的 strokeEnd 属性设置动画。代码可能如下所示:

 This function animates showing or hiding the checkmark view's layer by animating the layer's strokeEnd property.

 - Parameter show: If true, show the checkmark. If false, hide it.
 - Parameter animationDuration: the duration of the animation, in seconds.
 - Parameter animationCurve: Indicates the animation timing curve to use, .linear or .easeInEaseOut
*/
public func animateCheckmarkStrokeEnd(_ show: Bool,
                                      animationDuration: Double = 0.3,
                                      animationCurve: AnimationCurve = .linear) {
    guard let layer = layer as? CAShapeLayer else { return }
    let newStrokeEnd: CGFloat = show ? 1.0 : 0.0
    let oldStrokeEnd: CGFloat = show ? 0.0 : 1.0

    let keyPath = "strokeEnd"
    let animation = CABasicAnimation(keyPath: keyPath)
    animation.fromValue = oldStrokeEnd
    animation.toValue = newStrokeEnd
    animation.duration = animationDuration
    let timingFunction: CAMediaTimingFunction
    if animationCurve == .linear {
        timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.linear)
    } else {
        timingFunction = CAMediaTimingFunction(name: CAMediaTimingFunctionName.easeInEaseOut)
    }
    animation.timingFunction = timingFunction
    layer.add(animation, forKey: nil)
    DispatchQueue.main.async {
        layer.strokeEnd = newStrokeEnd
    }
    self.checked = show
}

整个演示应用程序允许您将复选标记动画创建为笔画动画或交叉淡入淡出,并允许您使用线性时序或缓入/缓出时序。演示应用程序的窗口如下所示:

在此处输入图像描述


¹:您可以创建其他蒙版动画,从右到左、从上到下、从中心向外等显示视图的内容。但是,对于您问题中的复选标记动画,您需要的蒙版动画将是左-向右“擦除”动画。


推荐阅读