Swift - 动画效果的实现方法总结(附样例)
(本文代码已升级至Swift3)
一,使用 animate 来实现动画
(1)此方法共有5个参数:
- withDuration:动画从开始到结束的持续时间,单位是秒
- delay:动画开始前等待的时间
- options:动画执行的选项。里面可以设置动画的效果。可以使用 UIViewAnimationOptions 类提供的各种预置效果
- anmations:动画效果的代码块
- completion:动画执行完毕后执行的代码块
- frame:此属性包含一个矩形,即边框矩形,此值确定了当前视图在其父视图坐标系中的位置与尺寸
- bounds:也是矩形,边界矩形,它指的是视图在其自己的坐标系中的位置和尺寸,左上角坐标永远是 (0,0)
- center:确定视图的中心点在其父视图坐标系中的位置坐标。即定义当前视图在父视图中的位置
- alpha:视图的透明度。(但视图完全透明时,不能响应触摸消息)
- backgroundColor:背景色
- transform:这是一种 3×3 的变化矩阵。通过这个矩阵我们可以对一个坐标系统进行缩放、平移、旋转以及这两者的任意组操作。
- CGAffineTransformMake():返回变换矩阵
- CGAffineTransformMakeTranslation():返回平移变换矩阵
- CGAffineTransformMakeScale():返回缩放变换矩阵
- CGAffineTransformMakeRotation():返回旋转变换矩阵



1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 | import UIKit class ViewController : UIViewController { //游戏方格维度 var dimension: Int = 4 //数字格子的宽度 var width: CGFloat = 50 //格子与格子的间距 var padding: CGFloat = 6 //保存背景图数据 var backgrounds: Array < UIView >! override func viewDidLoad() { super .viewDidLoad() self .backgrounds = Array < UIView >() setupGameMap() playAnimation() } func setupGameMap() { var x: CGFloat = 50 var y: CGFloat = 150 for i in 0..<dimension { print (i) y = 150 for _ in 0..<dimension { //初始化视图 let background = UIView (frame: CGRect (x:x, y:y, width:width, height:width)) background.backgroundColor = UIColor .darkGray self .view.addSubview(background) //将视图保存起来,以备后用 backgrounds.append(background) y += padding + width } x += padding+width } } func playAnimation() { for tile in backgrounds{ //先将数字块大小置为原始尺寸的 1/10 tile.layer.setAffineTransform( CGAffineTransform (scaleX: 0.1,y: 0.1)) //设置动画效果,动画时间长度 1 秒。 UIView .animate(withDuration: 1, delay:0.01, options: [], animations: { ()-> Void in //在动画中,数字块有一个角度的旋转。 tile.layer.setAffineTransform( CGAffineTransform (rotationAngle: 90)) }, completion:{ (finished: Bool ) -> Void in UIView .animate(withDuration: 1, animations:{ ()-> Void in //完成动画时,数字块复原 tile.layer.setAffineTransform( CGAffineTransform .identity) }) }) } } override func didReceiveMemoryWarning() { super .didReceiveMemoryWarning() } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | func playAnimation() { for tile in backgrounds{ //先将数字块大小置为原始尺寸的 1/10 tile.layer.setAffineTransform( CGAffineTransform (scaleX: 0.1,y: 0.1)) //设置动画效果,动画时间长度 1 秒。 UIView .animate(withDuration: 1, delay:0.01, options:[], animations: { ()-> Void in tile.layer.setAffineTransform( CGAffineTransform (scaleX: 1,y: 1)) }, completion:{ (finished: Bool ) -> Void in UIView .animate(withDuration: 0.08, animations:{ ()-> Void in tile.layer.setAffineTransform( CGAffineTransform .identity) }) }) } } |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 | func playAnimation() { for tile in backgrounds{ tile.alpha = 0 //设置动画效果,动画时间长度 1 秒。 UIView .animate(withDuration: 1, delay:0.01, options:[.curveEaseInOut], animations: { ()-> Void in }, completion:{ (finished: Bool ) -> Void in UIView .animate(withDuration: 1, animations:{ ()-> Void in tile.alpha = 1 }) }) } } |
二,使用 beginAnimations 和 commitAnimations 方法来实现动画
- beginAnimations:此方法开始一个动画块,调用 commitAnimations 结束一个动画块,并且动画块是允许嵌套的。
- commitAnimations:此方法用于结束一个动画块,动画是在一个独立的线程中运行的,动画在生效时,所有应用程序不会中断。
(1)淡入,淡出,移动,改变大小动画
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | //淡出动画 UIView .beginAnimations( nil , context: nil ) UIView .setAnimationDuration(2.0) imageView.alpha = 0.0 UIView .commitAnimations() //淡入动画 UIView .beginAnimations( nil , context: nil ) UIView .setAnimationDuration(2.0) imageView.alpha = 1.0 UIView .commitAnimations() //移动动画 UIView .beginAnimations( nil , context: nil ) UIView .setAnimationDuration(2.0) imageView.center = CGPoint (x:250, y:250) UIView .setAnimationCurve(.easeOut) //设置动画相对速度 UIView .commitAnimations() //大小调整动画 UIView .beginAnimations( nil , context: nil ) UIView .setAnimationDuration(2.0) imageView.frame = CGRect (x:100, y:180, width:50, height:50) UIView .commitAnimations() |
(2)两个视图切换的过渡动画
UIViewAnimationTransition定义了 5 种过渡动画类型:
- none:无过渡动画效果
- flipFromLeft:从左侧向右侧翻转
- flipFromRight:从右侧向左侧翻转
- curlUp:向上卷数翻页
- curlDown:向下翻页
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 | import UIKit class ViewController : UIViewController { override func viewDidLoad() { super .viewDidLoad() //创建一个按钮,用来点击播放动画 let button: UIButton = UIButton (type:.system) button.frame= CGRect (x:10, y:20, width:100, height:30) button.setTitle( "播放动画" , for :.normal) button.addTarget( self ,action:#selector( ViewController .play), for :.touchUpInside) self .view.addSubview(button) //添加两个红蓝视图 let redView = UIView (frame: CGRect (x:50, y:50, width:150, height:400)) redView.backgroundColor = UIColor .red self .view.insertSubview(redView, at: 0) let blueView = UIView (frame: CGRect (x:50, y:50, width:150, height:400)) blueView.backgroundColor = UIColor .blue self .view.insertSubview(blueView, at: 1) } //切换视图并播放动画 func play(){ UIView .beginAnimations( nil , context: nil ) UIView .setAnimationDuration(3.0) UIView .setAnimationTransition(.curlUp, for : self .view, cache: true ) self .view.exchangeSubview(at: 1, withSubviewAt: 0) UIView .commitAnimations() } override func didReceiveMemoryWarning() { super .didReceiveMemoryWarning() } } |
(3)页面或元件翻转效果
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 | import UIKit class ViewController : UIViewController { override func viewDidLoad() { super .viewDidLoad() //创建一个按钮,用来点击播放动画 let button = UIButton (type:.system) button.frame = CGRect (x:10, y:20, width:100, height:30) button.setTitle( "播放动画" , for :.normal) button.addTarget( self ,action:#selector( ViewController .play), for :.touchUpInside) self .view.addSubview(button); } //切换视图并播放动画 func play(){ //将整个主视图面板实现一个翻转效果 UIView .beginAnimations( "animation" , context: nil ) UIView .setAnimationDuration(2) UIView .setAnimationCurve(.easeInOut) UIView .setAnimationTransition(.flipFromLeft, for : self .view, cache: false ) UIView .commitAnimations() } override func didReceiveMemoryWarning() { super .didReceiveMemoryWarning() } } |
想问一下 我有两个viewcontroller 第二个里面写有动画效果 我从第一个present到第二个之后第二个vc里面的动画就不执行了直接显示结果?
如果我想把这些方块变成按钮呢 可以嘛? 具体可以描述一下该怎么实现嘛 谢谢!