代码改变世界

用 Swift 语言写一个地图坐标弹跳动画

2015-07-20 22:09  迷思的猫  阅读(1558)  评论(1编辑  收藏  举报

模仿“一号专车”写一个坐标图标弹跳动画,实现效果如下:(录制有点闪小心狗眼)

分析这个动画如下:
1.easeIn或者linear被抬高约30像素
2.被弹性放下

然后开始了狗血的 Swift animation 之旅。

注意:因为我刚刚开始学习 iOS 开发,动画亦是刚刚接触,下面的方式仅仅是为了完成需求,下面的文章并没有解释动画实现的细节,也不太可能是实现这个需求的最好方式,仅仅是“实现了”而已,只作为一个参考。我还会继续探索里面的细节,以后在博客里更新。

再注意:本文已经有了“加强版”(http://www.cnblogs.com/missingcat92/p/4673267.html),建议直接看加强版,以免被本文误导。

第一步,实现

先抛开那些蛋疼的物理效果不谈,先把它抬起,然后放下吧。。。(渣渣博客园竟然没有 Swift 语法高亮)

let animation = CABasicAnimation(keyPath: "position.y")
animation.autoreverses = true // 跑上去之后,给我滚回来
animation.duration = 0.2
animation.byValue = -30
locateImage.layer.addAnimation(animation, forKey: "bounce")

效果如下:

恭喜我已经完成了“嘀嘀打车”的效果模拟,万里长征第一步。

第二步,美化

直上直下意思虽然到了,但是感觉不对,我首先非常逗比地加了这么一行代码:

animation.timingFunction = CAMediaTimingFunction(name: kCAMediaTimingFunctionEaseOut)

这显然是。。没有任何卵用的。。典型的撞大运编程。。

于是我开始潜心修炼。。。

其实我们刚才已经很冷静的分析过了,一个linear动画,一个弹性放下,linear自然是好实现,关键问题在于后面那个。

一番 Google 无果后,开始认真学起了 CABasicAnimation,发现有个开源类库叫做 RBBAnimation。

如同孙猴子发现了大蟠桃,赶紧通过 CocoaPods 放入项目。在 pod install 完成后,创建了 xx-Bridging-Header.h 文件,内容如下:

#include <RBBAnimation/RBBAnimation.h>

然后在 .swift 文件中引入:

import RBBAnimation

再写弹跳下坠的动画

let animationDown = RBBTweenAnimation(keyPath: "position.y")
animationDown.fromValue = self.locateImage.layer.position.y
animationDown.toValue = self.locateImage.layer.position.y + 30
animationDown.easing = RBBEasingFunctionEaseOutBounce;
animationDown.duration = 0.7
self.locateImage.layer.addAnimation(animationDown, forKey: "bounceDown")

效果如下:

请不要在意最后一秒小标又滚回原位,是 CABasicAnimation 的正常表现。。

第三步,整合完善

现在把两段动画站在一起,并且加上位移的代码

CATransaction.begin()

let animationUp = CABasicAnimation(keyPath: "position.y")
animationUp.duration = 0.2
animationUp.fromValue = locateImage.layer.position.y
animationUp.toValue = locateImage.layer.position.y - 30

CATransaction.setCompletionBlock({
    let animationDown = RBBTweenAnimation(keyPath: "position.y")
    animationDown.fromValue = self.locateImage.layer.position.y
    animationDown.toValue = self.locateImage.layer.position.y + 30
    animationDown.easing = RBBEasingFunctionEaseOutBounce;
    animationDown.duration = 0.7
    self.locateImage.layer.addAnimation(animationDown, forKey: "bounceDown")
    self.locateImage.layer.position.y += 30
})

locateImage.layer.addAnimation(animationUp, forKey: "bounceUp")
locateImage.layer.position.y -= 30

CATransaction.commit()

效果如下:

参考:

动画解释:
http://objccn.io/issue-12-1/

RBBAnimation:
https://github.com/robb/RBBAnimation

Animation End Callback for CALayer?
http://stackoverflow.com/questions/296967/animation-end-callback-for-calayer

延伸:

SKBounceAnimation(弹跳动画库):https://github.com/khanlou/SKBounceAnimation

Some techniques for bouncing animations in iOS:http://www.touchwonders.com/blog/some-techniques-for-bouncing-animations-in-ios

Basic UIView Animation with Swift Tutorial:http://www.raywenderlich.com/76200/basic-uiview-animation-swift-tutorial

UIKit Dynamics 教程:抛掷 Views:http://www.tuicool.com/articles/BFjiUj