Build your custom Activityindicator View with Swift

Source: Internet
Author: User

Currently in its own personal project, Swift is already being used to write code. This article shows you a activityindicator view that you have designed in your project.

Before we start, let's look at the final results, such as:

I recommend that you download this article for a complete project shared on GitHub so that you can follow this article to read the code.

Demand analysis

We need to implement a loading effect that customizes and Uiactivityindicatorview provides similar functionality. We'll use the Core Graphics to draw this effect and make it move.

Let us first analyze the composition of this control, for our actual coding to provide specific ideas.

First, this loading is a circle of 8 arcs.

We're going to draw arcs first:

Draw 8 arcs like this, and surround them with a circle:

Then change the color of each arc by repeating it to make it move.

We inherit UIView, rewrite the DrawRect method to draw the interface, the first step to get the context of the current drawing:

1 let context = UIGraphicsGetCurrentContext()

Drawing arcs

Here we use the Uibezierpath class to build the path and then draw the arc by drawing the path.

1234567891011121314151617 // 初始化一个 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)

By the way above, we can successfully draw an arc. which

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

The interpretation of this method's build path is that center is the dot coordinate, radius is radius, startangle is the starting Radian, Endangle is the arc of the end, clockwise is the clockwise or counterclockwise.

Draw 8 Arcs

When we can successfully draw an arc in the drawing context, we should start by drawing 8 arcs in the correct position and take a different color.

Here are some parameter settings, including information such as radius, width, color, etc.:

12345678 struct Config {    static let CC_ACTIVITY_INDICATOR_VIEW_WIDTH = 40    static let CC_ARC_DRAW_PADDING = 3.0    static let CC_ARC_DRAW_DEGREE = 39.0    static let CC_ARC_DRAW_WIDTH = 6.0    static let CC_ARC_DRAW_RADIUS = 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, alpha:  1.0). Cgcolor, uicolor (Red: 179/255.0, green: 179/255.0, blue: 179/255.0, alpha:  1.0). Cgcolor, uicolor (Red: 128/255.0, green: 128/255.0, blue: 128/255.0, alpha:  1.0). Cgcolor, uicolor (Red: 128/255.0, green: 128/255.0, blue: 128/255.0, alpha:  1.0). Cgcolor, uicolor (Red: 128/255.0, green: 128/255.0, blue: 128/255.0, alpha:  1.0). Cgcolor, uicolor (Red: 128/255.0, green: 128/255.0, blue: 128/255.0, alpha:  1.0). Cgcolor, uicolor (Red: 128/255.0, green: 128/255.0, blue: 128/255.0, alpha:  1.0). CGcolor]     }

We can draw 8 arcs in the DrawRect method, and in this case the complete code looks like this:

12345678910111213141516171819 override func drawRect(rect: CGRect) {    let context = UIGraphicsGetCurrentContext()    varstartAngle = Config.CC_ARC_DRAW_PADDING    forindex in1...8 {        let arcPath = UIBezierPath()        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)        startAngle += Config.CC_ARC_DRAW_DEGREE + (Config.CC_ARC_DRAW_PADDING * 2)        CGContextSetLineWidth(context, CGFloat(Config.CC_ARC_DRAW_WIDTH))        let colorIndex = abs(index - self.animateIndex)        let strokeColor = Config.CC_ARC_DRAW_COLORS[colorIndex]        CGContextSetStrokeColorWithColor(context, strokeColor)        CGContextStrokePath(context)    }}

Draws 8 times with a For loop, produces 8 arcs, and sets a different color. Here the Self.animateindex is used to track the position of the lightest arc of the first color of the entire animation. Gets the color that the current arc should display by using it and the absolute value of the current index.

Move it

When designing a activityindicator view, we should, like the Uiactivityindicatorview provided by Uikit, implement at least these three sets of APIs:

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

Here we use a timer to change the value of the self.animateindex and constantly redraw the current view to produce an animated effect, and the code looks like this:

12345678910111213141516171819202122232425262728293031 // 使用该值驱动改变圆弧颜色,产生动画效果private varanimateIndex: Int = 1// 动画的Timerprivate var animatedTimer: NSTimer?// timer响应的事件,在这里setNeedsDisplay让UIKit重画当前视图,然后不断改变animateIndex值。@objc private func animate () {    if!self.hidden {        self.setNeedsDisplay()        self.animateIndex++        if self.animateIndex > 8 {            self.animateIndex = 1        }    }}// 开始动画func startAnimating () {    ifself.hidden {        self.hidden = false    }    iflet timer = self.animatedTimer {        timer.fire()    else{        self.animatedTimer = NSTimer(timeInterval: 0.1, target: self, selector: "animate", userInfo: nil, repeats: true)        NSRunLoop.currentRunLoop().addTimer(self.animatedTimer!, forMode: NSRunLoopCommonModes)    }}

Used here

1 init(timeInterval ti: NSTimeInterval, target aTarget: AnyObject, selector aSelector: Selector, userInfo: AnyObject?, repeats yesOrNo: Bool) -> NSTimer

Instead of using

1 class func scheduledTimerWithTimeInterval(ti: NSTimeInterval, target aTarget: AnyObject, selector aSelector: Selector, userInfo: AnyObject?, repeats yesOrNo: Bool) -> NSTimer

The reason to build the timer is that when we use our own activityindicator view, we may put it on the Uiscrollview. This time the timer created with Scheduledtimerwithtimeinterval is added to the current run loop, while Uiscrollview receives the user interaction event, the main thread run Loop is set to Uitrackingrunloopmode. This time will cause the timer to fail. In a more detailed answer, I'm walking into the world of Run Loop (a): What is a run loop? is stated in the article.

Summarize

By this time, we should be able to see and the same animation effect. However, when writing a custom control that is available for use, you should consider more detail work. For example, initialization, view removal, intrinsiccontentsize, support for @IBInspectable and @IBDesignable, etc., to make the developer of our control more friendly. More detailed code and demo can go here to view: Https://github.com/yechunjun/CCActivityIndicatorView

Build your custom Activityindicator View with Swift

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.