您可以捐助,支持我们的公益事业。

1元 10元 50元





认证码:  验证码,看不清楚?请点击刷新验证码 必填



  求知 文章 文库 Lib 视频 iPerson 课程 认证 咨询 工具 讲座 Modeler   Code  
会员   
 
   
 
 
     
   
 订阅
  捐助
CALayer Animation实践(三):iPhone经典滑动解锁动画
 
作者:付宇轩 来源:CSDN 发布于: 2015-09-24
  3225  次浏览      16
 

摘要:本文为CALayer Animation系列第三篇。时至今日,无论iPhone机身样式如何改变,屏幕尺寸如何改变,iOS系统如何改变,唯有锁屏底部闪烁的滑动来解锁不变。它的动画效果是如何实现的呢?这篇文章会告诉你们答案。

在很多人的心目中iPhone的经典机型应该是iPhone4,精湛的工艺、完美的屏幕配上暗色的锁屏壁纸,看着屏幕底部闪烁的slide to unlock字样,高逼格彰显无遗。时至今日无论iPhone机身样式如何改变,屏幕尺寸如何改变,iOS系统如何改变,唯有锁屏底部闪烁的滑动来解锁不变。它的动画效果是如何实现的呢,这篇文章会告诉你们答案。

CAGradientLayer

新建一个应用名为GradientAnimation,打开Main.storyboard,将ViewController的View背景色设置为灰黑色,拖一个UIView到ViewController中,将其颜色设置为无色并设置好布局约束:

接着我们拖一个UILabel到刚才拖入的UIView中,设置高宽等同于它的父视图:

我对该UILabel的属性设置如下:

之后,我们在ViewController中添加UIView和UILabel的Outlet:

接下来回到ViewController.swift,我们添加一个常量属性gradientLayer:

let gradientLayer = CAGradientLayer()  

这里出现了CALayer的另一个子类CAGradientLayer,这个类的作用就是能在Layer上绘制出渐变颜色的效果,然后在viewDidLoad()中添加如下代码:

gradientLayer.bounds = CGRect(x: 0, y: 0, 
width: backgroundView.frame.size.width, height: backgroundView.frame.size.height)
gradientLayer.position = CGPoint(x: backgroundView.frame.size.width/2,
y: backgroundView.frame.size.height/2)

上述两行的代码是设置Layer的大小及位置,这在上两篇文章中已经讲过,这里就不再累赘了。接着我们继续添加两行代码:

gradientLayer.startPoint = CGPoint(x: 0, y: 0.5)  
gradientLayer.endPoint = CGPoint(x: 1, y: 0.5)

既然CAGradientLayer可以绘制出渐变颜色的效果,那自然有颜色渐变的方向,所以这两行代码的作用就是设置颜色渐变的起始点和结束点,这两个属性共同决定了颜色渐变的方向:

从上面的示意图中可以看出,CAGradientLayer是通过起始点和结束点的坐标位置来决定颜色渐变的方向的,起始点的默认值是(0.5, 0),结束点的默认值是(0.5, 1),也就是说默认的颜色渐变方向是沿垂直中线从上往下渐变的,我们在这里将它改成了沿水平中线从左往右渐变。

接下来我们设置CAGradientLayer的渐变颜色,接着添加如下代码:

gradientLayer.colors = [  
UIColor.blackColor().CGColor,
UIColor.whiteColor().CGColor,
UIColor.blackColor().CGColor
]

CAGradientLayer的colors属性类型是一个数组[AnyObject],这就意味着我们可以实现多个颜色的渐变效果,并且可以规定各个颜色的顺序。不过在我们这个示例中我们只需要两种颜色,不过需要注意的是虽然颜色只有两种,但是整个颜色渐变的过程中有三个原色点,那就是黑、白、黑,所以我们在这个数组中也需要按照原色点的数量和顺序添加相应的颜色,哪怕颜色都是一样的。

我们既然设置了渐变的三个原色,那么就要对这原色出现的位置进行设置,接着添加如下代码:

gradientLayer.locations = [0.2, 0.5, 0.8] 

从上述代码中不难看出,我们将第一个黑色原色出现的位置设置在了整个Layer长度的十分之二的位置,第二个白色原色在中间,第三个黑色原色在十分之八的位置:

设置完CAGradientLayer的相关属性后,我们将gradientLayer添加到backgroundView的Layer中:

backgroundView.layer.addSublayer(gradientLayer)  

现在我们编译运行一下代码看看效果:

接下来我们需要让颜色渐变动起来,先创建一个方法gradinetAnimate(),在方法中添加如下代码:

let gradient = CABasicAnimation(keyPath: "locations")  
gradient.fromValue = [0, 0, 0.25]
gradient.toValue = [0.75, 1, 1]
gradient.duration = 2.5
gradient.repeatCount = HUGE
gradientLayer.addAnimation(gradient, forKey: nil)

首先,创建了一个locations类型的动画实例gradient,将fromValue属性,也就是起始位置的属性设置为[0, 0, 0.25],它的意思是动画开始前,黑色、白色这两个原色的位置在整个Layer的最前端,第二个黑色原色在0.25的位置:

而结束位置toValue,将白色和第二个黑色原色位置设置在整个Layer的末端,第一个黑色原色在0.75的位置:

从图中可以看出,此时整个Layer都变成了黑色。也就是说,在整个动画中,第一个黑色原色从0移动到0.75的位置,白色原色从0移动到1的位置,第二个黑色原色从0.25移动到1的位置。然后设置动画时间为2.5秒,无线重复次数,最后将gradient动画添加到gradientLayer中。我们在viewDidAppear()方法中调用该动画方法gradientAnimate(),编译运行看看效果:

动画效果还不赖,但是如何将颜色渐变的动画作用在UILabel的文字上呢?其实非常简单,就是让UILabel上的文字称为CAGradientLayer的遮罩即可,我们先在ViewController中定义一个常量:

var text = "DevTalking" 

然后在viewDidAppear()中的gradientAnimate()方法之前添加如下代码:

textLabel.text = text  
gradientLayer.mask = textLabel.layer

我们再编译运行代码看看效果:

到目前为止,锁屏中滑动来解锁的动画效果就完成了,这个动画效果在Facebook的Paper应用中也有使用。下一节,我们在该动画的基础上对文字再加点小动画。

Text Animation

首先我们打开AppDelegate.swift,在import UIKit下面添加一个方法:

func delay(seconds seconds: Double, completion:()->()) {  
let intervalTime = dispatch_time(DISPATCH_TIME_NOW, Int64( Double(NSEC_PER_SEC) * seconds ))

dispatch_after(intervalTime, dispatch_get_main_queue(), {
completion()
})
}

这个方法的作用如其名称一样,是一个延迟方法,该方法的第一个参数是想要延迟的时间,第二个参数是一个闭包,也就是延迟的主体。这个方法用到了GCD的知识,dispatch_time主要是用于创建一个类型为dispatch_time_t的相对时间,它的第一个参数指的是起始时间,一般都是用预定义的DISPATCH_TIME_NOW作为第一个参数的值,代表当前的时间。第二个参数代表时间间隔,注意这个参数需要的时间单位是纳秒,所以我们使用预定义的NSEC_PER_SEC纳秒单位乘以希望间隔的秒数。

dispatch_after用于在队列中定时执行任务,当你想在一段时间后执行一个任务,那么就可以用这个函数。该函数的第一个参数指定延迟的时间,第二个参数指定一个队列,用于添加任务,第三个参数是一个闭包,也就是要执行的任务。

然后回到ViewController.swift,添加如下方法:

func textAnimate(text: String) {  
if text.characters.count > 0 {
textLabel.text = "\(textLabel.text!)\(text.substringToIndex(text.startIndex.successor()))"
delay(seconds: 0.4, completion: {
self.textAnimate(text.substringFromIndex(text.startIndex.successor()))
})
}
}

该方法的参数text就是UILabel中要显示的文字内容。substringToIndex(_ to: Int)方法的作用是从字符串的开头一直截取到指定的位置,但不包括该指定位置的字符。text.startIndex.successor()这句意思是从text的起始位置开始取后面的一个字符。substringFromIndex(_ from: Int)方法的作用是以指定位置并包括指定位置的字符开始,一直截取之后的全部字符。所以整个方法的作用是每隔0.4秒显示一个字符,直到将整个字符串显示完。最后在viewDidAppear()中注释掉textLabel.text = text这行代码,并在方法最后调用textAnimate(text)方法。编译运行代码看看最终效果:

   
3225 次浏览       16
 
相关文章

手机软件测试用例设计实践
手机客户端UI测试分析
iPhone消息推送机制实现与探讨
Android手机开发(一)
 
相关文档

Android_UI官方设计教程
手机开发平台介绍
android拍照及上传功能
Android讲义智能手机开发
相关课程

Android高级移动应用程序
Android系统开发
Android应用开发
手机软件测试
最新课程计划
信息架构建模(基于UML+EA)3-21[北京]
软件架构设计师 3-21[北京]
图数据库与知识图谱 3-25[北京]
业务架构设计 4-11[北京]
SysML和EA系统设计与建模 4-22[北京]
DoDAF规范、模型与实例 5-23[北京]

android人机界面指南
Android手机开发(一)
Android手机开发(二)
Android手机开发(三)
Android手机开发(四)
iPhone消息推送机制实现探讨
手机软件测试用例设计实践
手机客户端UI测试分析
手机软件自动化测试研究报告
更多...   


Android高级移动应用程序
Android应用开发
Android系统开发
手机软件测试
嵌入式软件测试
Android软、硬、云整合


领先IT公司 android开发平台最佳实践
北京 Android开发技术进阶
某新能源领域企业 Android开发技术
某航天公司 Android、IOS应用软件开发
阿尔卡特 Linux内核驱动
艾默生 嵌入式软件架构设计
西门子 嵌入式架构设计
更多...