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

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()
}
}
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)
})
})
}
}
(6)样例3:方块从不透明到透明的效果
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)淡入,淡出,移动,改变大小动画
//淡出动画 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:向下翻页
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)页面或元件翻转效果
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()
}
}
全部评论(2)
想问一下 我有两个viewcontroller 第二个里面写有动画效果 我从第一个present到第二个之后第二个vc里面的动画就不执行了直接显示结果?
站长回复:我这边测试了下第二个VC中的动画也是执行的,不太清楚你那边是什么问题了。
如果我想把这些方块变成按钮呢 可以嘛? 具体可以描述一下该怎么实现嘛 谢谢!
站长回复:按钮UIButton是UIView的子类,所以可以直接将方块(UIView)替换成按钮实现同样的动画效果。