0、动画基础
主要动画属性
1、XY坐标属性:Position(左上角为原点)
2、透明度属性:Opacity(透明:0.0,不透明:1.0)
3、缩放属性:Scale(调整对象的尺寸,如对话框的显示)
4、其他属性:Color(颜色属性)、Rotate(旋转属性)、3D属性(如3D翻转)
思考动画是如何形成的
1、动画开始时对象的属性
2、动画结束时对象的属性
3、动画执行的时间
4、在动画执行过程中会发生什么
5、动画结束后会发生什么
动画曲线
1、线性匀速变化(Linear)
2、以慢速开始:加速变化(Ease In)
3、先加速后减速的变化(Ease In,Ease Out)
4、以慢速结束:减速变化(Ease Out)
1、UIKit和Core Animation
架构
UIKit(iOS) and Appkit(OS X) Core Animation OpenGL ES and OpenGL Core Graphics Graphics Hardware |
实例
//创建 let redBall = UIView(frame: CGRectMake(50, 50, 100, 100)) redBall.backgroundColor = UIColor.redColor() redBall.layer.cornerRadius = 50 self.view.addSubview(redBall)
//球的放大动画 UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in redBall.transform = CGAffineTransformMakeScale(2, 2) }) { (finished:Bool) -> Void in print("finished") } |
override func viewDidLoad() { super.viewDidLoad() //创建 let redBall = UIView(frame: CGRectMake(50, 50, 100, 100)) redBall.backgroundColor = UIColor.redColor() redBall.layer.cornerRadius = 50 self.view.addSubview(redBall)
//球的放大动画 UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
// redBall.transform = CGAffineTransformMakeScale(2, 2) //组合动画,CGAffineTransformConcat redBall.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(2.0, 2.0), CGAffineTransformMakeTranslation(150, 50))
}) { (finished:Bool) -> Void in print("finished") } } |
组合动画:CGAffineTransformConcat
override func viewDidLoad() { super.viewDidLoad() //创建 let redBall = UIView(frame: CGRectMake(50, 50, 100, 100)) redBall.backgroundColor = UIColor.redColor() redBall.layer.cornerRadius = 50 self.view.addSubview(redBall)
//球的放大动画 UIView.animateWithDuration(0.5, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in
// redBall.transform = CGAffineTransformMakeScale(2, 2) //组合动画,CGAffineTransformConcat redBall.transform = CGAffineTransformConcat(CGAffineTransformMakeScale(2.0, 2.0), CGAffineTransformMakeTranslation(150, 50)) redBall.backgroundColor = UIColor.greenColor() }) { (finished:Bool) -> Void in print("finished") } } |
弹性动画(spring Animation),iOS 7.0以后有此动画
//创建 let redBall = UIView(frame: CGRectMake(50, 50, 100, 100)) redBall.backgroundColor = UIColor.redColor() redBall.layer.cornerRadius = 50 self.view.addSubview(redBall)
//弹性动画,iOS 7.0以后有此动画 UIView.animateWithDuration(2.0, delay: 0, usingSpringWithDamping: 0.3,//弹性阻尼,取值范围是0-1,越接近0,动画的弹性效果就越明显;如果设置为1,则动画不会有弹性效果 initialSpringVelocity: 0,//视图在动画开始时的速度,通常都应该传入0 options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in redBall.transform = CGAffineTransformConcat( CGAffineTransformMakeScale(2, 2),CGAffineTransformMakeTranslation(150, 50) )
redBall.backgroundColor = UIColor.greenColor()
}) { (finished:Bool) -> Void in print("finished") } |
2、JNWSpringAnimation,详细调整参数
前言
CAKeyframeAnimation(关键帧动画) 多个关键帧组成动画 可以设置时间间隔 设置位移,缩放等动画属性 |
JNW支持的属性
位置:position 边界:bounds 阴影:shadow 圆角:corner 缩放:scale 旋转:rotation |
JNW帧率为6帧的动画,1秒6帧
缩放动画
//创建 let redBall = UIView(frame: CGRectMake(50, 50, 100, 100)) redBall.backgroundColor = UIColor.redColor() redBall.layer.cornerRadius = 50 self.view.addSubview(redBall)
//缩放动画 //创建JNW实例,keyPath跟CALayer一样 let scale = JNWSpringAnimation(keyPath: "transform.scale")
//阻尼固有频率是指有阻尼的机械系统的自由振动频率。由系统的质量、弹性系数和阻力系数决定,可表示为 式中:K为弹性系数;R为阻力系数,M为质量。
//阻尼,决定动画的衰减,默认为30 scale.damping = 6 //弹性系数,弹簧伸缩的难度,决定动画的振幅,默认为300 scale.stiffness = 100 //质量,决定动画快慢的效果,默认为5 scale.mass = 2 //设置初始值 scale.fromValue = 1 //设置结束值 scale.toValue = 2 //将JNW赋予redball redBall.layer.addAnimation(scale, forKey: scale.keyPath) //jnwspring animation默认会还原初始状态,所以要手动设置到结束状态 redBall.transform = CGAffineTransformMakeScale(2, 2) |
旋转动画
//创建 let redBall = UIView(frame: CGRectMake(50, 50, 100, 100)) redBall.backgroundColor = UIColor.redColor() // redBall.layer.cornerRadius = 50 self.view.addSubview(redBall)
//旋转动画 //创建jnw对象 let rotation = JNWSpringAnimation(keyPath: "transform.rotation") //设置阻尼值 rotation.damping = 6 //设置弹性系数 rotation.stiffness = 100 //设置质量 rotation.mass = 2
//设置初始值和结束值 rotation.fromValue = 0 rotation.toValue = M_PI_4
redBall.layer.addAnimation(rotation, forKey: rotation.keyPath) //防止动画后还原 redBall.transform = CGAffineTransformMakeRotation(CGFloat(M_PI_4)) |
位移动画
//创建 let redBall = UIView(frame: CGRectMake(50, 50, 100, 100)) redBall.backgroundColor = UIColor.redColor() // redBall.layer.cornerRadius = 50 self.view.addSubview(redBall)
//位移动画 //创建jnw对象 let translation = JNWSpringAnimation(keyPath: "transform.translation.x") //设置阻尼值 translation.damping = 6 //设置弹性系数 translation.stiffness = 100 //设置质量 translation.mass = 2
//设置初始值和结束值 translation.fromValue = 0 translation.toValue = 100
//添加动画 redBall.layer.addAnimation(translation, forKey: translation.keyPath) //防止动画还原 redBall.transform = CGAffineTransformMakeTranslation(100, 0) |
组合动画 :JNW实例+JNW实例=JNW组合动画,即分别加入不同的动画即可。
关于渲染的三棵树
模型树:静态数据,在执行动画时不会改变
表现树:记录执行动画时的动画数据
渲染树:屏幕渲染,私有的
自定义警告框
1、半透明背景层淡入动画
2、警告框透明度0-1动画,尺寸由1.2变为1
3、警告框消失,透明度变为0,缩小尺寸
4、半透明背景层消失
func application(application: UIApplication, didFinishLaunchingWithOptions launchOptions: [NSObject: AnyObject]?) -> Bool {
//窗口的代码 //窗口尺寸 self.window = UIWindow(frame: UIScreen.mainScreen().bounds) //设置窗口背景颜色 self.window?.backgroundColor = UIColor.whiteColor() //激活窗口 self.window?.makeKeyAndVisible()
self.window?.rootViewController = ViewController()
//灰色的遮挡层 //遮挡层的frame let overlayView = UIView(frame: self.window!.bounds) //设置颜色 overlayView.backgroundColor = UIColor.blackColor() //设置透明度,应该为0 //TODO: 改为0 overlayView.alpha = 0 //加入场景 self.window?.addSubview(overlayView)
//警告框相关代码 //警告框的宽高 let alertDimension:CGFloat = 250.0 //警告框的frame let alertViewFrame = CGRectMake(self.window!.bounds.width/2 - alertDimension/2, self.window!.bounds.height / 2 - alertDimension/2, alertDimension, alertDimension) //实例化警告框 let alertView = UIView(frame: alertViewFrame) //设置警告框背景 alertView.backgroundColor = UIColor(patternImage: UIImage(named: "alert_box")!) //设置警告框的透明度,应该为0 //TODO: 改为0 alertView.alpha = 0 //设置警告框的初始尺寸为1.2倍 alertView.transform = CGAffineTransformMakeScale(1.2, 1.2) //设置警告框的圆角半径 alertView.layer.cornerRadius = 10
//设置阴影 //颜色 alertView.layer.shadowColor = UIColor.blackColor().CGColor //阴影偏移 alertView.layer.shadowOffset = CGSizeMake(0, 0.5) //阴影透明度 alertView.layer.shadowOpacity = 0.3 //阴影尺寸,跟警告框的圆角半径对应 alertView.layer.shadowRadius = 10
//将警告框加入当前窗口 self.window?.addSubview(alertView)
//延时设置 var minseconds = 1 * Double(NSEC_PER_SEC) var dtime = dispatch_time(DISPATCH_TIME_NOW, Int64(minseconds)) dispatch_after(dtime, dispatch_get_main_queue()) { () -> Void in
//显示动画 UIView.animateWithDuration(0.3, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in //背景和警告框显示出来 overlayView.alpha = 0.3 alertView.alpha = 1 }, completion: nil)
//jnw实例 let scale = JNWSpringAnimation(keyPath: "transform.scale") //阻尼值 scale.damping = 14 //弹性系数 scale.stiffness = 440 //质量 scale.mass = 1 //初始值 scale.fromValue = 1.2 //结束值 scale.toValue = 1 //执行动画 alertView.layer.addAnimation(scale, forKey: scale.keyPath) //更新一下执行完动画后的scale值,防止还原 alertView.transform = CGAffineTransformMakeScale(1, 1) }
minseconds = 3 * Double(NSEC_PER_SEC) dtime = dispatch_time(DISPATCH_TIME_NOW, Int64(minseconds)) dispatch_after(dtime, dispatch_get_main_queue()) { () -> Void in //消失动画 UIView.animateWithDuration(0.15, delay: 0, options: UIViewAnimationOptions.CurveEaseInOut, animations: { () -> Void in overlayView.alpha = 0 alertView.alpha = 0 }, completion: nil)
//jnw实例,变小 let scaleOut = JNWSpringAnimation(keyPath: "transform.scale") scaleOut.damping = 14 scaleOut.stiffness = 14 scaleOut.mass = 1 scaleOut.fromValue = 1 scaleOut.toValue = 0.7
alertView.layer.addAnimation(scaleOut, forKey: scaleOut.keyPath) alertView.transform = CGAffineTransformMakeScale(0.7, 0.7)
let translation = JNWSpringAnimation(keyPath: "transform.translation.y") translation.damping = 14 translation.stiffness = 14 translation.mass = 1 translation.fromValue = self.window!.bounds.size.height/2 - alertDimension/2 translation.toValue = self.window!.bounds.size.height alertView.layer.addAnimation(translation, forKey: translation.keyPath) } return true } |
3、Facebook Pop(Facebook Paper)
适用所有的对象。
使用pod引入pop
实例
//添加一个红球 let redBall = UIView(frame: CGRectMake(100, 100, 100, 100)) redBall.backgroundColor = UIColor.redColor() redBall.layer.cornerRadius = 50 self.view.addSubview(redBall)
//增加pop动画 //实例化一个pop对象 let scale = POPSpringAnimation(propertyNamed: kPOPViewScaleXY) //fromValue默认为原来的值 //设置结束值,放大2倍 scale.toValue = NSValue(CGPoint:CGPointMake(2, 2)) //设置弹性,振幅之类的属性,值范围0-20 scale.springBounciness = 20 //设置震动速度,值越大动画结束速度越快,范围0-20 scale.springSpeed = 1 //加入pop动画,forKey,随便取值,唯一即可 redBall.pop_addAnimation(scale, forKey: "scaleAnimation") |
//添加一个红球 let redBall = UIView(frame: CGRectMake(100, 100, 100, 100)) redBall.backgroundColor = UIColor.redColor() // redBall.layer.cornerRadius = 50 self.view.addSubview(redBall)
//旋转动画 //x坐标位移动画,PositionX从100->300 let move = POPSpringAnimation(propertyNamed: kPOPLayerPositionX) move.toValue = 300 move.springBounciness = 20 move.springSpeed = 5 redBall.layer.pop_addAnimation(move, forKey: "moveAnimation")
//旋转动画 let rotation = POPSpringAnimation(propertyNamed: kPOPLayerRotation) rotation.toValue = M_PI * 4 //2圈 rotation.springBounciness = 20 rotation.springSpeed = 5 redBall.layer.pop_addAnimation(rotation, forKey: "rotationAnimation")
//背景颜色变化 let color = POPSpringAnimation(propertyNamed: kPOPViewBackgroundColor) color.toValue = UIColor.greenColor() color.springBounciness = 20 color.springSpeed = 5 redBall.pop_addAnimation(color, forKey: "colorAnimation") |
更多POP的实例参考网址:https://github.com/facebook/pop