使用 Swift 构建自定义的ActivityIndicator View

编程之家收集整理的这篇文章主要介绍了使用 Swift 构建自定义的ActivityIndicator View编程之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。

搜索热词

本文由@Chun发表于Chun Tips :http://chun.tips/blog/2014/12/11/shi-yong-swift-gou-jian-zi-ding-yi-de-activityindicator-view/

目前在自己的个人项目里,已经开始使用Swift去编写代码。这篇文章把项目中自己设计的一个ActivityIndicator View展示给大家。

在开始之前,我们先看看最终的效果,如下图:


我建议大家下载本文对应在Github分享的完整项目:https://github.com/yechunjun/CCActivityIndicatorView,以便跟着本篇文章来阅读代码。

需求分析

我们需要实现一个自定义的和 UIActivityIndicatorView 提供相似功能的一个Loading效果。我们将使用 Core Graphics 来绘制这样的效果,并使用 Core Animation让它动起来。

让我们先分析一下这个控件的组成,为我们实际编码提供具体的思路。

首先,这个loading效果图,是由8个圆弧组成的一个圆。

我们先要会画圆弧:

像这样画8个不同颜色的圆弧,围成一个圆,形成动画的一帧:

实现该动画至少需要8种不同情况的圆,然后通过Core Animation的CAKeyframeAnimation关键帧动画让它动起来。

绘制圆弧

这里我们使用 UIBezierPath 类去构建路径,然后通过绘制路径的方式绘制圆弧。

let context = UIGraphicsGetCurrentContext()

// 初始化一个 UIBezierPath 实例
let arcPath = UIBezierPath()

// 构建Arc路径
arcPath.addArcWithCenter(CGPointMake(CGFloat(self.frame.size.width/2),CGFloat(self.frame.size.height/2)),radius: CGFloat(Config.CC_ARC_DRAW_RADIUS),startAngle: CGFloat(DegreesToRadians(startAngle)),endAngle: CGFloat(DegreesToRadians(startAngle + Config.CC_ARC_DRAW_DEGREE)),clockwise: true)

// 把路径添加到当前绘图的上下文
CGContextAddPath(context,arcPath.CGPath)

// 设置线段宽度
CGContextSetLineWidth(context,CGFloat(Config.CC_ARC_DRAW_WIDTH))

// 设置线段颜色
CGContextSetStrokeColorWithColor(context,strokeColor)

// 绘制        
CGContextStrokePath(context)

通过如上的方式,我们就可以成功画出一个圆弧。其中:

func addArcWithCenter(center: CGPoint,radius: CGFloat,startAngle: CGFloat,endAngle: CGFloat,clockwise: Bool)

这个方法构建路径的解释是 center 为圆点坐标,radius 为半径,startAngle 为开始的弧度,endAngle 为结束的弧度,clockwise 表示的是顺时针还是逆时针。
绘制一帧Contents:8个圆弧

当我们可以成功在绘图上下文绘制出圆弧时,我们应该开始着手绘制效果图中的8个圆弧,并让它在正确的位置,带上不同颜色。

这里是效果图的一些参数设置,包括半径,宽度,颜色等信息:

static let CC_ACTIVITY_INDICATOR_VIEW_NUMBEROFFRAMES: Int = 8
static let CC_ACTIVITY_INDICATOR_VIEW_WIDTH: CGFloat = 40
static let CC_ARC_DRAW_PADDING: CGFloat = 3.0
static let CC_ARC_DRAW_DEGREE: CGFloat = 39.0
static let CC_ARC_DRAW_WIDTH: CGFloat = 6.0
static let CC_ARC_DRAW_RADIUS: CGFloat = 10.0
static let CC_ARC_DRAW_COLORS = [UIColor(red: 242/255.0,green: 242/255.0,blue: 242/255.0,alpha: 1.0).CGColor,UIColor(red: 230/255.0,green: 230/255.0,blue: 230/255.0,UIColor(red: 179/255.0,green: 179/255.0,blue: 179/255.0,UIColor(red: 128/255.0,green: 128/255.0,blue: 128/255.0,alpha: 1.0).CGColor]

我们可以在循坏中绘制8个圆弧,生成一张image,做为动画的一帧,此时完整的代码看上去像这样:

static func CCActivityIndicatorViewFrameImage(frame: Int,_ scale: CGFloat) -> UIImage {

    // 创建一个基于位图的上下文(context)
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(CC_ACTIVITY_INDICATOR_VIEW_WIDTH,CC_ACTIVITY_INDICATOR_VIEW_WIDTH),false,scale)

    let context = UIGraphicsGetCurrentContext()

    var startDegree = Config.CC_ARC_DRAW_PADDING
    for index in 1...8 {
        let arcPath = UIBezierPath()
        let center  = CGPointMake(Config.CC_ACTIVITY_INDICATOR_VIEW_WIDTH / 2,Config.CC_ACTIVITY_INDICATOR_VIEW_WIDTH / 2)
        let startAngle = CGFloat(DegreesToRadians(Double(startDegree)))
        let endAngle = CGFloat(DegreesToRadians(Double(startDegree + Config.CC_ARC_DRAW_DEGREE)))
        arcPath.addArcWithCenter(center,radius: Config.CC_ARC_DRAW_RADIUS,startAngle: startAngle,endAngle: endAngle,clockwise: true)
        CGContextAddPath(context,arcPath.CGPath)
        startDegree += Config.CC_ARC_DRAW_DEGREE + (Config.CC_ARC_DRAW_PADDING * 2)
        CGContextSetLineWidth(context,Config.CC_ARC_DRAW_WIDTH)
        let colorIndex = abs(index - frame)
        let strokeColor = Config.CC_ARC_DRAW_COLORS[colorIndex]
        CGContextSetStrokeColorWithColor(context,strokeColor)
        CGContextStrokePath(context)
    }

    let image = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()

    return image
}

使用for循环绘制8次,产生8个圆弧,并且设置不同的颜色。这里的frame用来确定当前image所处的帧数。通过它和当前index的绝对值,我们可以获得当前圆弧应该显示的颜色。
动起来

在设计一个ActivityIndicator View的时候,我们应该像UIKit提供的 UIActivityIndicatorView 一样,至少需要实现这三组API:

func startAnimating()
func stopAnimating()
func isAnimating() -> Bool

感谢 @传人Joe的评价,这里把原先通过timer执行的动画换成了CoreAnimation来实现。

func startAnimating () {

    func animate () {
        self.animating = true

        let animationDuration: CFTimeInterval = 0.8

        // 构造一组动画所需的images
        var animationImages = [CGImageRef]()
        for frame in 1...Config.CC_ACTIVITY_INDICATOR_VIEW_NUMBEROFFRAMES {
            animationImages.append(Config.CCActivityIndicatorViewFrameImage(frame,UIScreen.mainScreen().nativeScale).CGImage)
        }

        // 使用Core Animation关键帧CAKeyframeAnimation构建动画
        let animation = CAKeyframeAnimation(keyPath: "contents")
        animation.calculationMode = kCAAnimationDiscrete
        animation.duration = animationDuration
        animation.repeatCount = HUGE
        animation.values = animationImages
        animation.removedOnCompletion = false
        animation.fillMode = kCAFillModeBoth
        self.layer.addAnimation(animation,forKey: "contents")
    }

    if !self.animating {
        animate()
    }
}

func stopAnimating () {
    self.animating = false

    self.layer.removeAnimationForKey("contents")
    self.layer.contents = Config.CCActivityIndicatorViewFrameImage(0,UIScreen.mainScreen().nativeScale).CGImage
}

这里需要注意的是:考虑不同iPhone分辨率的情况,我们在绘制image作为视图Layer的contents的时候,使用UIScreen.mainScreen().nativeScale的大小构造image context上下文环境
总结

到这个时候,我们应该就能看到和效果图一样的动画效果。但是写一个可供使用的自定义控件时,应该考虑更多的细节工作。比如初始化,视图移除,intrinsicContentSize,是否需要支持 @IBInspectable 和 @IBDesignable 等等,来让使用我们控件的开发者更加友好。更加详细的代码和Demo可以去这里查看:https://github.com/yechunjun/CCActivityIndicatorView



推荐几篇阅读量最高的文章

1. 推荐:打造高效率iOS开发实战交流VIP群

2. 一个程序员这辈子需要挣多少钱才能维系一个家庭?

3. VIP群福利:Git使用教程(视频+PPT)

总结

以上是编程之家为你收集整理的使用 Swift 构建自定义的ActivityIndicator View全部内容,希望文章能够帮你解决使用 Swift 构建自定义的ActivityIndicator View所遇到的程序开发问题。

如果觉得编程之家网站内容还不错,欢迎将编程之家网站推荐给程序员好友。

本图文内容来源于网友网络收集整理提供,作为学习参考使用,版权属于原作者。
如您喜欢寻找一群志同道合、互帮互助的学习伙伴,可以点击下方链接加入:
编程之家官方1群:1065694478(已满)
编程之家官方2群:163560250(已满)
编程之家官方3群:312128206(已满)
编程之家官方4群:230427597

相关文章

猜你在找的Swift相关文章

1. 安装 clang 编译器clang 编译器是苹果公司提供的 C 编译器,是 Swift 必需的一个组件。在终端运行下面命令执行安装sudo apt-get --assume-yes install clang或者去 Ubuntu 软件中心搜索 Clang 安装即可极客在安装Clang的时候出现过以下问题解决方法:打开Ub
Swift 正式开源!Swift 团队很高兴宣布 Swift 开始开源新篇章。自从苹果发布 Swfit 编程语言,就成为了历史上发展最快的编程语言之一。Swift 通过设计使得软件编写更加快速更加安全。 Swift 的 GitHub 地址:https://github.com/apple/swift Swift 是由多种不同的项目组成的,提供一个构建软件的完整生态系统。Swift 编译器项目解析
开发者(KaiFaX) 面向开发者、程序员的专业平台! 和今年年初承诺的一样,苹果贴出了Swift语言的源码,宣布该语言正式开源。值得注意的是,除了Swift,苹果还开源了两个项目:Swfit核心库项目和全新的Swift包管理器项目。 Swift的开源是开发者社区的一个胜利,因这意味着这个语言将可以用于服务器等其它领域,而苹果的开发者也不再是只能用它来为Mac和iOS开发App。 让Swift开源
本文由@Chun发表于Chun Tips :http://chun.tips/blog/2014/12/11/shi-yong-swift-gou-jian-zi-ding-yi-de-activityindicator-view/ 目前在自己的个人项目里,已经开始使用Swift去编写代码。这篇文章把项目中自己设计的一个ActivityIndicator View展示给大家。 在开始之前,我们先看
本文由CocoaChina译者leon(社区ID)翻译 原文:THE RIGHT WAY TO WRITE A SINGLETON 在之前的帖子里聊过状态管理有多痛苦,有时这是不可避免的。一个状态管理的例子大家都很熟悉,那就是单例。使用Swift时,有许多方法实现单例,这是个麻烦事,因为我们不知道哪个最合适。这里我们来回顾一下单例的历史,看一看在Swift中如何正确地实现单例。 如果你想直接看看S
本文由CocoaChina译者leon(社区ID)翻译 原文:THE RIGHT WAY TO WRITE A SINGLETON 在之前的帖子里聊过状态管理有多痛苦,有时这是不可避免的。一个状态管理的例子大家都很熟悉,那就是单例。使用Swift时,有许多方法实现单例,这是个麻烦事,因为我们不知道哪个最合适。这里我们来回顾一下单例的历史,看一看在Swift中如何正确地实现单例。 如果你想直接看看S
★ 时间就是金钱。你可以一开始就使用正确的 Swift 教程来节省时间。本文中提到的教程都是这方面的专家写的可靠的教程。 Swift 是一门相对比较新的编程语言,深受广大苹果社区开发者的喜爱。在短短不到一年的时间,很多很多开发者已经转向使用 Swift 编程语言了。苹果开发者们接受 Swift,纯粹是因为 Swfit 更加先进,安全,容易,快速,而且包含适合现代应用开发所需要的所有特性。 在开发
CSDN移动将持续为您优选移动开发的精华内容,共同探讨移动开发的技术热点话题,涵盖移动应用、开发工具、移动游戏及引擎、智能硬件、物联网等方方面面。如果您想投稿、寻求《近匠》报道,或给文章挑错,欢迎发送邮件至tangxy@csdn.net。 不久之前,苹果宣布Swift正式开源,皆大欢喜。又多了好多好玩的新玩意儿,一时间仿佛提前过圣诞了呢!而其中的Swift包管理器(Swift Package Ma