IOS开发入门之教你写 Slack 的 Loading 动画
白羽 2018-11-23 来源 :网络 阅读 820 评论 0

摘要:本文将带你了解IOS开发入门iOS动画进阶 - 手摸手教你写 Slack 的 Loading 动画,希望本文对大家学IOS有所帮助。

    本文将带你了解IOS开发入门iOS动画进阶 - 手摸手教你写 Slack 的 Loading 动画,希望本文对大家学IOS有所帮助。



        

老规矩先上图和demo地址:

刚看到这个动画的时候,脑海里出现了两个方案,一种是通过drawRect画出来,然后配合CADisplayLink不停的绘制线的样式;第二种是通过CAShapeLayer配合CAAnimation来实现动画效果。再三考虑觉得使用后者,因为前者需要计算很多,比较复杂,而且经过测试前者相比于后者消耗更多的CPU,下面将我的思路写下来:<喎?"/kf/ware/vc/" target="_blank" class="keylink">vcD4NCjxoMSBpZD0="相关配置和初始化方法">相关配置和初始化方法

在写这个动画之前,我们把先需要的属性写好,比如线条的粗细,动画的时间等等,下面是相关的配置和初识化方法:


   

<code><code><code>    //线的宽度

    var lineWidth:CGFloat = 0

    //线的长度

    var lineLength:CGFloat = 0

    //边距

    var margin:CGFloat = 0

    //动画时间

    var duration:Double = 2

    //动画的间隔时间

    var interval:Double = 1

    //四条线的颜色

    var colors:[UIColor] = [UIColor.init(rgba: "#9DD4E9") , UIColor.init(rgba: "#F5BD58"),  UIColor.init(rgba: "#FF317E") , UIColor.init(rgba: "#6FC9B5")]

    //动画的状态

    private(set) var status:AnimationStatus = .Normal

    //四条线

    private var lines:[CAShapeLayer] = []

 

    enum AnimationStatus {

        //普通状态

        case Normal

        //动画中

        case Animating

        //暂停

        case pause

    }

 

     //MARK: Initial Methods

    convenience init(fram: CGRect , colors: [UIColor]) {

        self.init()

        self.frame = frame

        self.colors = colors

        config()

    }

 

    override init(frame: CGRect) {

        super.init(frame: frame)

        config()

    }

 

    required init?(coder aDecoder: NSCoder) {

        super.init(coder: aDecoder)

        config()

    }

 

    private func config() {

        lineLength = max(frame.width, frame.height)

        lineWidth  = lineLength/6.0

        margin     = lineLength/4.5 + lineWidth/2

        drawLineShapeLayer()

        transform = CGAffineTransformRotate(CGAffineTransformIdentity, angle(-30))

    }</code></code></code>

   

通过CAShapeLayer绘制线条

看到这个线条我就想到了用CAShapeLayer来处理,因为CAShapeLayer完全可以实现这种效果,而且它的strokeEnd的属性可以用来实现线条的长度变化的动画,下面上绘制四根线条的代码:


   

<code><code><code><code><code><code>//MARK: 绘制线

    /**

     绘制四条线

     */

    private func drawLineShapeLayer() {

        //开始点

        let startPoint = [point(lineWidth/2, y: margin),

                          point(lineLength - margin, y: lineWidth/2),

                          point(lineLength - lineWidth/2, y: lineLength - margin),

                          point(margin, y: lineLength - lineWidth/2)]

        //结束点

        let endPoint   = [point(lineLength - lineWidth/2, y: margin) ,

                         point(lineLength - margin, y: lineLength - lineWidth/2) ,

                         point(lineWidth/2, y: lineLength - margin) ,

                         point(margin, y: lineWidth/2)]

        for i in 0...3 {

            let line:CAShapeLayer = CAShapeLayer()

            line.lineWidth   = lineWidth

            line.lineCap     = kCALineCapRound

            line.opacity     = 0.8

            line.strokeColor = colors[i].CGColor

            line.path        = getLinePath(startPoint[i], endPoint: endPoint[i]).CGPath

            layer.addSublayer(line)

            lines.append(line)

        }

 

    }

 

    /**

     获取线的路径

 

     - parameter startPoint: 开始点

     - parameter endPoint:   结束点

 

     - returns: 线的路径

     */

    private func getLinePath(startPoint: CGPoint, endPoint: CGPoint) -> UIBezierPath {

        let path = UIBezierPath()

        path.moveToPoint(startPoint)

        path.addLineToPoint(endPoint)

        return path

    }

 

    private func point(x:CGFloat , y:CGFloat) -> CGPoint {

        return CGPointMake(x, y)

    }

 

    private func angle(angle: Double) -> CGFloat {

        return CGFloat(angle *  (M_PI/180))

    }</code></code></code></code></code></code>

   

执行完后就跟上图一样的效果了~~~

动画分解

经过分析,可以将动画分为四个步骤:

画布的旋转动画,旋转两圈 线条由长变短的动画,更画布选择的动画一起执行,旋转一圈的时候结束 线条的位移动画,线条逐渐向中间靠拢,再画笔旋转完一圈的时候执行,两圈的时候结束 线条由短变长的动画,画布旋转完两圈的时候执行 

第一步画布旋转动画

这里我们使用CABasicAnimation基础动画,keyPath作用于画布的transform.rotation.z,以z轴为目标进行旋转,下面是效果图和代码:


   

<code><code><code><code><code><code><code><code><code>//MARK: 动画步骤

    /**

     旋转的动画,旋转两圈

     */

    private func angleAnimation() {

        let angleAnimation                 = CABasicAnimation.init(keyPath: "transform.rotation.z")

        angleAnimation.fromValue           = angle(-30)

        angleAnimation.toValue             = angle(690)

        angleAnimation.fillMode            = kCAFillModeForwards

        angleAnimation.removedOnCompletion = false

        angleAnimation.duration            = duration

        angleAnimation.delegate            = self

        layer.addAnimation(angleAnimation, forKey: "angleAnimation")

    }</code></code></code></code></code></code></code></code></code>

   

第二步线条由长变短的动画

这里我们还是使用CABasicAnimation基础动画,keyPath作用于线条的strokeEnd属性,让strokeEnd从1到0来实现线条长短的动画,下面是效果图和代码:

   

本文由职坐标整理并发布,希望对同学们有所帮助。了解更多详情请关注职坐标移动开发之IOS频道!


本文由 @白羽 发布于职坐标。未经许可,禁止转载。
喜欢 | 0 不喜欢 | 0
看完这篇文章有何感觉?已经有0人表态,0%的人喜欢 快给朋友分享吧~
评论(0)
后参与评论

您输入的评论内容中包含违禁敏感词

我知道了

助您圆梦职场 匹配合适岗位
验证码手机号,获得海同独家IT培训资料
选择就业方向:
人工智能物联网
大数据开发/分析
人工智能Python
Java全栈开发
WEB前端+H5

请输入正确的手机号码

请输入正确的验证码

获取验证码

您今天的短信下发次数太多了,明天再试试吧!

提交

我们会在第一时间安排职业规划师联系您!

您也可以联系我们的职业规划师咨询:

小职老师的微信号:z_zhizuobiao
小职老师的微信号:z_zhizuobiao

版权所有 职坐标-一站式IT培训就业服务领导者 沪ICP备13042190号-4
上海海同信息科技有限公司 Copyright ©2015 www.zhizuobiao.com,All Rights Reserved.
 沪公网安备 31011502005948号    

©2015 www.zhizuobiao.com All Rights Reserved

208小时内训课程