iOS动画:复制图层(10)

语音输入时,有没有考虑过下面两种波浪形动画是怎么生成的呢?
image_1
没错,它就是我们今天需要了解的,图层复制动画CAReplicatorLayer。
首先我们先来看一个例子。
1.将CALayer复制多次添加到CAReplicatorLayer图层上面
创建属性

    let replicator = CAReplicatorLayer()//复制图层(父图层)
    let dot = CALayer()//显示图层(子图层)
    let dotLength: CGFloat = 6.0//子图层的宽高
    let dotOffset: CGFloat = 8.0//子图层的偏移量

将图层在viewDidLoad里面添加到view.layer上面

    replicator.frame = view.bounds//让replicator层和viewController坐标相同
    view.layer.addSublayer(replicator)
    
    dot.frame = CGRect(x: replicator.frame.size.width - dotLength, y: replicator.position.y, width: dotLength, height: dotLength)//设置子图层的坐标,x坐标居右,y坐标为屏幕中间位置
    dot.backgroundColor = UIColor.lightGray.cgColor
    dot.borderColor = UIColor(white: 1.0, alpha: 1.0).cgColor
    dot.borderWidth = 0.5
    dot.cornerRadius = 1.5
    replicator.addSublayer(dot)//将子图层添加到replicator层
    
    replicator.instanceCount = Int(view.frame.size.width / dotOffset)//根据屏幕宽度,设置copy数量
    replicator.instanceTransform = CATransform3DMakeTranslation(-dotOffset, 0.0, 0.0)//设置偏移量,让所有的copy都显示在屏幕上

运行效果
image_2
添加动画

	// This is a test animation, you're going to delete it
    let move = CABasicAnimation(keyPath: "position.y")
    move.fromValue = dot.position.y
    move.toValue = dot.position.y - 50.0
    move.duration = 1.0
    move.repeatCount = 10
    dot.add(move, forKey: nil)
	// This is the end of the code you're going to delete
	replicator.instanceDelay = 0.02//每个copy延迟0.02秒执行动画

运行效果
image_3
删除上面的测试动画,现在我们来创建一个波浪形动画。
在开始语音输入时,添加Scale动画:

    let scale = CABasicAnimation(keyPath: "transform")
    scale.fromValue = NSValue(caTransform3D: CATransform3DIdentity)
    scale.toValue = NSValue(caTransform3D: CATransform3DMakeScale(1.4, 15, 1.0))
    scale.duration = 0.33
    scale.repeatCount = .infinity
    scale.autoreverses = true
    scale.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
    dot.add(scale, forKey: "dotScale")

运行效果
image_4
添加Opacity动画

    let fade = CABasicAnimation(keyPath: "opacity")
    fade.fromValue = 1.0
    fade.toValue = 0.2
    fade.duration = 0.33
    fade.beginTime = CACurrentMediaTime() + 0.33
    fade.repeatCount = .infinity
    fade.autoreverses = true
    fade.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
    dot.add(fade, forKey: "dotOpacity")

运行效果
image_5
添加Tint动画

    let tint = CABasicAnimation(keyPath: "backgroundColor")
    tint.fromValue = UIColor.magenta.cgColor
    tint.toValue = UIColor.cyan.cgColor
    tint.duration = 0.66
    tint.beginTime = CACurrentMediaTime() + 0.28
    tint.fillMode = kCAFillModeBackwards
    tint.repeatCount = .infinity
    tint.autoreverses = true
    tint.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    dot.add(tint, forKey: "dotColor")

运行效果
image_6
前面我们对CAReplicatorLayer的子图层进行了一系列动画,我们也可以对CAReplicatorLayer本身添加一些动画,除了一些基本的position、backgroundColor、cornerRadius属性等等可以添加动画以外,它本身还有一些独有的属性可以添加动画,比如:instanceDelayinstanceTransforminstanceColorinstanceRedOffsetinstanceGreenOffsetinstanceBlueOffsetinstanceAlphaOffset
添加动画:

    let initialRotation = CABasicAnimation(keyPath: "instanceTransform.rotation")
    initialRotation.fromValue = 0.0
    initialRotation.toValue = 0.01
    initialRotation.duration = 0.33
    initialRotation.isRemovedOnCompletion = false
    initialRotation.fillMode = kCAFillModeBackwards
    initialRotation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)
    replicator.add(initialRotation, forKey: "initialRotation")
    
    let rotation = CABasicAnimation(keyPath: "instanceTransform.rotation")
    rotation.fromValue = 0.01
    rotation.toValue = -0.01
    rotation.duration = 0.99
    rotation.beginTime = CACurrentMediaTime() + 0.33
    rotation.repeatCount = .infinity
    rotation.autoreverses = true
    rotation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseInEaseOut)
    replicator.add(rotation, forKey: "replicatorRotation")

运行效果
image_7
移除动画

	replicator.removeAllAnimations()

这个remove方法仅仅移除了replicator的instanceTransform动画。
下一步将dot还原到原始的大小

    let scale = CABasicAnimation(keyPath: "transform")
    scale.toValue = NSValue(caTransform3D: CATransform3DIdentity)
    scale.duration = 0.33
    scale.isRemovedOnCompletion = false
    scale.fillMode = kCAFillModeForwards
    dot.add(scale, forKey: nil)

该动画不需要指定fromValue,Core Animation将自动从当前值缩放到toValue大小
然后移除dotColor和dotOpacity动画

    dot.removeAnimation(forKey: "dotColor")
    dot.removeAnimation(forKey: "dotOpacity")
    dot.backgroundColor = UIColor.lightGray.cgColor
    speakButton.isHidden = false

回到最初状态
image_8

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值