转载

CALayer Animation实践(一):让应用灵动起来!

CSDN移动将持续为您优选移动开发的精华内容,共同探讨移动开发的技术热点话题,涵盖移动应用、开发工具、移动游戏及引擎、智能硬件、物联网等方方面面。如果您想投稿、参与内容翻译工作,或寻求近匠报道,请发送邮件至tangxy#csdn.net(请把#改成@)。 

这篇文章通过两个加载动画向大家介绍CALayer的动画。按照面向对象的思想说,Layer其实就是一个模型类,像Java里的POJO类一样,它包含若干属性,并没有任何处理逻辑的方法,这些属性影响着显示在Layer中的内容。我们先来看看UIView和CALayer之间有什么区别和联系。

  • 联系:Layer是View背后的那个女人。每一个UIView后面都有对应的CALayer,大家看到的在UIView中显示的内容其实是在CALayer中。
  • 区别:
    • View有复杂的、各种组合的布局机制。Layer只有极简单的布局。
    • View可以响应用户交互。Layer不能响应用户交互。
    • View中的绘画逻辑有CPU执行。Layer中的绘画直接有GPU执行。
    • View有丰富的、功能强大的子类。Layer只有很少的几个子类。
    • View动画属性较少,局限性较大。Layer由于更底层、动画属性更多,所以可以实现出更灵活、更丰富的动画。

第一个CALayer动画

Layer动画系列的文章,我不准备系统的从简单到复杂的知识进行讲解,我会通过各种实战示例,示例中用到什么知识点就讲什么知识点。

第一个动画让我们来实现Google Chrome浏览器加载时页签上的等待动画:

CALayer Animation实践(一):让应用灵动起来!

新建项目 GoogleLoading ,打开 Main.storyboard ,拖拽一个UIView到ViewController中,添加好约束,自行设置ViewController和UIView的背景色,这里UIView的背景色我设置为无色:

CALayer Animation实践(一):让应用灵动起来!

然后添加该View的Outlet到 ViewController 中,这个UIView就是要展示加载动画的View:

@IBOutlet weak var loadingView: UIView!

打开 ViewController.swift ,申明一个常量属性 ovalShapleLayer

let ovalShapeLayer: CAShapeLayer = CAShapeLayer()

ovalShapleLayer 的类型是 CAShapleLayer ,它是 CALayer 的为数不多的子类之一。它的作用是在屏幕上画出各种形状,不论是简单的圆形、方形还是复杂的五角星或不规则图形都难不住它。 CAShapeLayer 有如下一些主要属性:

  • strokeColor:笔画颜色。
  • strokeStart:笔画开始位置。
  • strokeEnd:笔画结束位置。
  • fillColor:图形填充颜色。
  • lineWidth:笔画宽度,即笔画的粗细程度。
  • lineDashPattern:虚线模式。
  • path:图形的路径。
  • lineCap:笔画未闭合位置的形状。

我们之所要申明一个 CAShapeLayer ,是因为要用它在屏幕上画出一个圆形。下面在 viewDidLoad() 方法中添加如下代码:

ovalShapeLayer.strokeColor = UIColor.whiteColor().CGColor ovalShapeLayer.fillColor = UIColor.clearColor().CGColor ovalShapeLayer.lineWidth = 7

这几个属性刚才已经向大家介绍过了,这三行代码的意思是我们画出的圆形笔画颜色是白色,没有填充色,笔画的宽度为7。接着我们申明这个圆形的半径,使这个圆形的大小为容纳它视图大小的80%:

let ovalRadius = loadingView.frame.size.height/2 * 0.8

最后我们设置 ovalShapeLayer 的路径,这是最关键的一步,因为你要告知 CAShapeLayer 按照什么路径绘制图形,让我们接着添加如下代码:

ovalShapeLayer.path = UIBezierPath(ovalInRect: CGRect(x: loadingView.frame.size.width/2 - ovalRadius, y: loadingView.frame.size.height/2 - ovalRadius, width: ovalRadius * 2, height: ovalRadius * 2)).CGPath

这里出现了新面孔 UIBezierPath ,它可以创建基于矢量的路径,是Core Graphics框架关于path的封装。 UIBezierPath 可以定义简单的形状路径,如椭圆、矩形,或者有多个直线和曲线段组成的形状。在这里我们要使用它的初始化方法 init(ovalInRect rect: CGRect) 定义一个正圆的路径。设置完路径后,将 ovalShapeLayer 添加到 loadingView 视图的Layer中,它就可以按照设定好的路径在 loadingView 中绘制图形了:

loadingView.layer.addSublayer(ovalShapeLayer)

编译运行看看效果:

CALayer Animation实践(一):让应用灵动起来!

完美的一个圆形。接下来我们要做的是让这个圆只显示一部分,因为Google的加载动画只有大概五分之二的圆形轮廓。让我们继续将目光集中在 viewDidLoad() 方法中,在 loadingView.layer.addSublayer(ovalShapeLayer) 这行代码上面添加另一行代码:

ovalShapeLayer.strokeEnd = 0.4

上面的代码将 ovalShapeLayerstrokeEnd 属性设置为0.4,意思是 ovalShapeLayer 在绘制圆形时只画整个圆形的五分之二,即笔画结束的位置在整个圆形轮廓的五分之二处。编译运行看看效果:

CALayer Animation实践(一):让应用灵动起来!

看来是我们想要的效果,但是仍有一处细节需要我们完善,看看Google的加载动画,蓝色的部分圆形轮廓两头是圆形的,而我们的圆形轮廓两头是方形的。这个问题很好解决,仍然在 loadingView.layer.addSublayer(ovalShapeLayer) 这行代码上面添加一行代码:

ovalShapeLayer.lineCap = kCALineCapRound
正文到此结束
Loading...