当前位置: > > > Swift - 三层环状进度条组件开发(仿Apple Watch上运动记录圆圈)

Swift - 三层环状进度条组件开发(仿Apple Watch上运动记录圆圈)

Apple Watch发布的时候,上面的有个类型仪表盘一样的圆形刻度盘让人印象深刻。它使用红绿蓝三色圆圈分别表示用户的活动,锻炼,站立情况。让人一眼就能了解自己当天的运动状况。

下面,我们使用Swift语言仿造一个类似的组件,暂时取名叫彩虹进度条(RainbowProgressView)。

1,彩虹进度条开发
(1)同开发其它的自定义组件一样,我们还是通过继承 UIView 来实现。
(2)整个组件由三个圆弧组成,在 drawRect() 方法中绘制添加。
(3)组件提供内、中、外三个圆圈的半径、颜色、进度属性,以及圆圈宽度属性让用户设置。
(4)组件类和属性使用IB标识,让其在StoryBoard中也能自由设置属性,并实时渲染效果。

效果图如下:
            

组件代码如下:
import Foundation
import UIKit

@IBDesignable
class RainbowProgressView: UIView {
    //进度条颜色(内圈、中间、外圈)
    @IBInspectable var firstColor: UIColor = UIColor(
        red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0)
    @IBInspectable var secondColor: UIColor = UIColor(
        red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0)
    @IBInspectable var thirdColor: UIColor = UIColor(
        red: (238.0/255.0), green: (32.0/255), blue: (53.0/255.0), alpha: 1.0)
    
    //进度条半径(内圈、中间、外圈)
    @IBInspectable var innerCircleRadius:CGFloat = 20
    @IBInspectable var middleCircleRadius:CGFloat = 45
    @IBInspectable var outerCircleRadius:CGFloat = 70
    
    //进度0~1(内圈、中间、外圈)
    @IBInspectable var firstPercent:CGFloat = 0.75
    @IBInspectable var secondPercent:CGFloat = 0.75
    @IBInspectable var thirdPercent:CGFloat = 0.75
    
    //进度条宽度
    @IBInspectable var circleWeight:CGFloat = 16
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        backgroundColor = UIColor.clearColor()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        backgroundColor = UIColor.clearColor()
    }
    
    // 绘制
    override func drawRect(rect: CGRect) {
        // 添加三个环形进度条
        self.addCirle(innerCircleRadius, color: firstColor, percent: firstPercent)
        self.addCirle(middleCircleRadius, color: secondColor, percent: secondPercent)
        self.addCirle(outerCircleRadius, color: thirdColor, percent: thirdPercent)
    }
    
    //添加环形进度
    func addCirle(arcRadius: CGFloat, color: UIColor, percent:CGFloat) {
        let X = CGRectGetMidX(self.bounds)
        let Y = CGRectGetMidY(self.bounds)
        
        // 进度条圆弧
        let barPath = UIBezierPath(arcCenter: CGPoint(x: X, y: Y), radius: arcRadius,
            startAngle: CGFloat(-M_PI_2), endAngle: CGFloat(M_PI*1.5),
            clockwise: true).CGPath
        self.addOval(circleWeight, path: barPath, strokeStart: 0, strokeEnd: percent,
            strokeColor: color, fillColor: UIColor.clearColor(),
            shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
    }
    
    //添加圆弧
    func addOval(lineWidth: CGFloat, path: CGPathRef, strokeStart: CGFloat,
        strokeEnd: CGFloat, strokeColor: UIColor, fillColor: UIColor,
        shadowRadius: CGFloat, shadowOpacity: Float, shadowOffsset: CGSize) {
        
        let arc = CAShapeLayer()
        arc.lineWidth = lineWidth
        arc.path = path
        arc.strokeStart = strokeStart
        arc.strokeEnd = strokeEnd
        arc.strokeColor = strokeColor.CGColor
        arc.fillColor = fillColor.CGColor
        arc.shadowColor = UIColor.blackColor().CGColor
        arc.shadowRadius = shadowRadius
        arc.shadowOpacity = shadowOpacity
        arc.shadowOffset = shadowOffsset
        layer.addSublayer(arc)
    }
}

测试代码:
import UIKit

class ViewController: UIViewController {

    override func viewDidLoad() {
        super.viewDidLoad()
        
        let rainbow1 = RainbowProgressView(frame: CGRectMake(5,20,160,160))
        self.view.addSubview(rainbow1)
        
        let rainbow2 = RainbowProgressView(frame: CGRectMake(175,20,140,140))
        rainbow2.circleWeight = 18
        rainbow2.innerCircleRadius = 20
        rainbow2.middleCircleRadius = 40
        rainbow2.outerCircleRadius = 60
        rainbow2.firstPercent = 0.5
        rainbow2.secondPercent = 0.65
        rainbow2.thirdPercent = 0.75
        self.view.addSubview(rainbow2)
    }

    override func didReceiveMemoryWarning() {
        super.didReceiveMemoryWarning()
    }
}

2,组件功能改进之一:圆弧两端增加圆头
为了让圆弧没有那么生硬,我们在圆弧的两端分别添加两个圆形,这样会更圆润些。同时终点上的圆形增加了个阴影,这样效果会更好些。
            
改进后的组件代码(高亮处为修改的地方):
import Foundation
import UIKit

@IBDesignable
class RainbowProgressViewEx: UIView {
    //进度条颜色(内圈、中间、外圈)
    @IBInspectable var firstColor: UIColor = UIColor(
        red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0)
    @IBInspectable var secondColor: UIColor = UIColor(
        red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0)
    @IBInspectable var thirdColor: UIColor = UIColor(
        red: (238.0/255.0), green: (32.0/255), blue: (53.0/255.0), alpha: 1.0)
    
    //进度条半径(内圈、中间、外圈)
    @IBInspectable var innerCircleRadius:CGFloat = 20
    @IBInspectable var middleCircleRadius:CGFloat = 45
    @IBInspectable var outerCircleRadius:CGFloat = 70
    
    //进度0~1(内圈、中间、外圈)
    @IBInspectable var firstPercent:CGFloat = 0.75
    @IBInspectable var secondPercent:CGFloat = 0.75
    @IBInspectable var thirdPercent:CGFloat = 0.75
    
    //进度条宽度
    @IBInspectable var circleWeight:CGFloat = 16
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        backgroundColor = UIColor.clearColor()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        backgroundColor = UIColor.clearColor()
    }
    
    // 绘制
    override func drawRect(rect: CGRect) {
        // 添加三个环形进度条
        self.addCirle(innerCircleRadius, color: firstColor, percent: firstPercent)
        self.addCirle(middleCircleRadius, color: secondColor, percent: secondPercent)
        self.addCirle(outerCircleRadius, color: thirdColor, percent: thirdPercent)
    }
    
    //添加环形进度
    func addCirle(arcRadius: CGFloat, color: UIColor, percent:CGFloat) {
        let X = CGRectGetMidX(self.bounds)
        let Y = CGRectGetMidY(self.bounds)
        
        // 进度条圆弧
        let barPath = UIBezierPath(arcCenter: CGPoint(x: X, y: Y), radius: arcRadius,
            startAngle: CGFloat(-M_PI_2), endAngle: CGFloat(M_PI*1.5),
            clockwise: true).CGPath
        self.addOval(circleWeight, path: barPath, strokeStart: 0, strokeEnd: percent,
            strokeColor: color, fillColor: UIColor.clearColor(),
            shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
        
        // 进度条起点圆头
        let startPath = UIBezierPath(ovalInRect: CGRectMake(X-circleWeight/2,
            Y-arcRadius-circleWeight/2, circleWeight, circleWeight)).CGPath
        self.addOval(0.0, path: startPath, strokeStart: 0, strokeEnd: 1.0,
            strokeColor: color, fillColor: color,
            shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
        
        // 进度条终点圆头
        let endDotPoint = calcCircleCoordinateWithCenter(CGPoint(x: X, y: Y),
            radius: arcRadius, angle: -percent*360+90)
        let endDotPath = UIBezierPath(ovalInRect: CGRectMake(endDotPoint.x-circleWeight/2,
            endDotPoint.y-circleWeight/2, circleWeight, circleWeight)).CGPath
        self.addOval(0.0, path: endDotPath, strokeStart: 0, strokeEnd: 1.0,
            strokeColor: color, fillColor: color,
            shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSizeZero)
    }
    
    //计算圆弧上点的坐标
    func calcCircleCoordinateWithCenter(center:CGPoint, radius:CGFloat, angle:CGFloat)
        -> CGPoint {
        let x2 = radius*CGFloat(cosf(Float(angle)*Float(M_PI)/Float(180)));
        let y2 = radius*CGFloat(sinf(Float(angle)*Float(M_PI)/Float(180)));
        return CGPointMake(center.x+x2, center.y-y2);
    }
    
    //添加圆弧
    func addOval(lineWidth: CGFloat, path: CGPathRef, strokeStart: CGFloat,
        strokeEnd: CGFloat, strokeColor: UIColor, fillColor: UIColor,
        shadowRadius: CGFloat, shadowOpacity: Float, shadowOffsset: CGSize) {
        
        let arc = CAShapeLayer()
        arc.lineWidth = lineWidth
        arc.path = path
        arc.strokeStart = strokeStart
        arc.strokeEnd = strokeEnd
        arc.strokeColor = strokeColor.CGColor
        arc.fillColor = fillColor.CGColor
        arc.shadowColor = UIColor.blackColor().CGColor
        arc.shadowRadius = shadowRadius
        arc.shadowOpacity = shadowOpacity
        arc.shadowOffset = shadowOffsset
        layer.addSublayer(arc)
    }
}

3,组件功能改进之二:添加进度条背景
看Apple Watch的运动状态圆盘可以发现,每个环形进度条后面还有一个相同色系的淡色进度槽,表示未完成的部分。
实现方式就是在各个进度条底部添加个透明圆环,颜色就是在其对应进度条颜色基础上增加透明度即可。
为了适应各种舞台背景,组件增加新属性 barBgAlpha,用于设置进度条底图的透明度。(黑色舞台背景建议0.3,白色舞台背景建议0.15)
            
改进后的组件代码(高亮处为修改的地方):
import Foundation
import UIKit

@IBDesignable
class RainbowProgressViewEx2: UIView {
    //进度条颜色(内圈、中间、外圈)
    @IBInspectable var firstColor: UIColor = UIColor(
        red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0)
    @IBInspectable var secondColor: UIColor = UIColor(
        red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0)
    @IBInspectable var thirdColor: UIColor = UIColor(
        red: (238.0/255.0), green: (32.0/255), blue: (53.0/255.0), alpha: 1.0)
    
    //进度条半径(内圈、中间、外圈)
    @IBInspectable var innerCircleRadius:CGFloat = 20
    @IBInspectable var middleCircleRadius:CGFloat = 45
    @IBInspectable var outerCircleRadius:CGFloat = 70
    
    //进度0~1(内圈、中间、外圈)
    @IBInspectable var firstPercent:CGFloat = 0.75
    @IBInspectable var secondPercent:CGFloat = 0.75
    @IBInspectable var thirdPercent:CGFloat = 0.75
    
    //进度条宽度
    @IBInspectable var circleWeight:CGFloat = 16
    
    //进度条背景槽透明度(黑色舞台背景建议0.3,白色舞台背景建议0.15)
    @IBInspectable var barBgAlpha:CGFloat = 0.3
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        backgroundColor = UIColor.clearColor()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        backgroundColor = UIColor.clearColor()
    }
    
    // 绘制
    override func drawRect(rect: CGRect) {
        // 添加三个环形进度条
        self.addCirle(innerCircleRadius, color: firstColor, percent: firstPercent)
        self.addCirle(middleCircleRadius, color: secondColor, percent: secondPercent)
        self.addCirle(outerCircleRadius, color: thirdColor, percent: thirdPercent)
    }
    
    //添加环形进度
    func addCirle(arcRadius: CGFloat, color: UIColor, percent:CGFloat) {
        let X = CGRectGetMidX(self.bounds)
        let Y = CGRectGetMidY(self.bounds)
        
        // 进度条圆弧背景
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        color.getRed(&r, green: &g, blue: &b, alpha: &a)
        let barBgColor = UIColor(red: r, green: g, blue: b, alpha: barBgAlpha);
        
        let barBgPath = UIBezierPath(arcCenter: CGPoint(x: X, y: Y), radius: arcRadius,
            startAngle: CGFloat(-M_PI_2), endAngle: CGFloat(M_PI*1.5),
            clockwise: true).CGPath
        self.addOval(circleWeight, path: barBgPath, strokeStart: 0, strokeEnd: 1,
            strokeColor: barBgColor, fillColor: UIColor.clearColor(),
            shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
        
        // 进度条圆弧
        let barPath = UIBezierPath(arcCenter: CGPoint(x: X, y: Y), radius: arcRadius,
            startAngle: CGFloat(-M_PI_2), endAngle: CGFloat(M_PI*1.5),
            clockwise: true).CGPath
        self.addOval(circleWeight, path: barPath, strokeStart: 0, strokeEnd: percent,
            strokeColor: color, fillColor: UIColor.clearColor(),
            shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
        
        // 进度条起点圆头
        let startPath = UIBezierPath(ovalInRect: CGRectMake(X-circleWeight/2,
            Y-arcRadius-circleWeight/2, circleWeight, circleWeight)).CGPath
        self.addOval(0.0, path: startPath, strokeStart: 0, strokeEnd: 1.0,
            strokeColor: color, fillColor: color,
            shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
        
        // 进度条终点圆头
        let endDotPoint = calcCircleCoordinateWithCenter(CGPoint(x: X, y: Y),
            radius: arcRadius, angle: -percent*360+90)
        let endDotPath = UIBezierPath(ovalInRect: CGRectMake(endDotPoint.x-circleWeight/2,
            endDotPoint.y-circleWeight/2, circleWeight, circleWeight)).CGPath
        self.addOval(0.0, path: endDotPath, strokeStart: 0, strokeEnd: 1.0,
            strokeColor: color, fillColor: color,
            shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSizeZero)
    }
    
    //计算圆弧上点的坐标
    func calcCircleCoordinateWithCenter(center:CGPoint, radius:CGFloat, angle:CGFloat)
                -> CGPoint {
        let x2 = radius*CGFloat(cosf(Float(angle)*Float(M_PI)/Float(180)));
        let y2 = radius*CGFloat(sinf(Float(angle)*Float(M_PI)/Float(180)));
        return CGPointMake(center.x+x2, center.y-y2);
    }
    
    //添加圆弧
    func addOval(lineWidth: CGFloat, path: CGPathRef, strokeStart: CGFloat,
        strokeEnd: CGFloat, strokeColor: UIColor, fillColor: UIColor,
        shadowRadius: CGFloat, shadowOpacity: Float, shadowOffsset: CGSize) {
            
            let arc = CAShapeLayer()
            arc.lineWidth = lineWidth
            arc.path = path
            arc.strokeStart = strokeStart
            arc.strokeEnd = strokeEnd
            arc.strokeColor = strokeColor.CGColor
            arc.fillColor = fillColor.CGColor
            arc.shadowColor = UIColor.blackColor().CGColor
            arc.shadowRadius = shadowRadius
            arc.shadowOpacity = shadowOpacity
            arc.shadowOffset = shadowOffsset
            layer.addSublayer(arc)
    }
}

4,组件功能改进之三:进度条终点只有突出的部分有阴影
前面的样例中,我门是在进度条终点处添加了一个圆来实现突出的部分,所以其阴影在这个圆点周围都是存在的。
如果想要只让突出的部分周围有阴影,我门在上方覆盖一小段圆弧即可,这样就将后半部分的阴影盖住。(注意:当进度条很短的时候还需在起点处覆盖个纯色的圆点才行) 
           

改进后的组件代码(高亮处为修改的地方):
import Foundation
import UIKit

@IBDesignable
class RainbowProgressViewEx3: UIView {
    //进度条颜色(内圈、中间、外圈)
    @IBInspectable var firstColor: UIColor = UIColor(
        red: (37.0/255.0), green: (252.0/255), blue: (244.0/255.0), alpha: 1.0)
    @IBInspectable var secondColor: UIColor = UIColor(
        red: (171.0/255.0), green: (250.0/255), blue: (81.0/255.0), alpha: 1.0)
    @IBInspectable var thirdColor: UIColor = UIColor(
        red: (238.0/255.0), green: (32.0/255), blue: (53.0/255.0), alpha: 1.0)
    
    //进度条半径(内圈、中间、外圈)
    @IBInspectable var innerCircleRadius:CGFloat = 20
    @IBInspectable var middleCircleRadius:CGFloat = 45
    @IBInspectable var outerCircleRadius:CGFloat = 70
    
    //进度0~1(内圈、中间、外圈)
    @IBInspectable var firstPercent:CGFloat = 0.75
    @IBInspectable var secondPercent:CGFloat = 0.75
    @IBInspectable var thirdPercent:CGFloat = 0.75
    
    //进度条宽度
    @IBInspectable var circleWeight:CGFloat = 16
    
    //进度条背景槽透明度(黑色舞台背景建议0.3,白色舞台背景建议0.15)
    @IBInspectable var barBgAlpha:CGFloat = 0.3
    
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
        
        backgroundColor = UIColor.clearColor()
    }
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        
        backgroundColor = UIColor.clearColor()
    }
    
    // 绘制
    override func drawRect(rect: CGRect) {
        // 添加三个环形进度条
        self.addCirle(innerCircleRadius, color: firstColor, percent: firstPercent)
        self.addCirle(middleCircleRadius, color: secondColor, percent: secondPercent)
        self.addCirle(outerCircleRadius, color: thirdColor, percent: thirdPercent)
    }
    
    //添加环形进度
    func addCirle(arcRadius: CGFloat, color: UIColor, percent:CGFloat) {
        let X = CGRectGetMidX(self.bounds)
        let Y = CGRectGetMidY(self.bounds)
        
        // 进度条圆弧背景
        var r: CGFloat = 0, g: CGFloat = 0, b: CGFloat = 0, a: CGFloat = 0
        color.getRed(&r, green: &g, blue: &b, alpha: &a)
        let barBgColor = UIColor(red: r, green: g, blue: b, alpha: barBgAlpha);
        
        let barBgPath = UIBezierPath(arcCenter: CGPoint(x: X, y: Y), radius: arcRadius,
            startAngle: CGFloat(-M_PI_2), endAngle: CGFloat(M_PI*1.5),
            clockwise: true).CGPath
        self.addOval(circleWeight, path: barBgPath, strokeStart: 0, strokeEnd: 1,
            strokeColor: barBgColor, fillColor: UIColor.clearColor(),
            shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
        
        // 进度条圆弧
        let barPath = UIBezierPath(arcCenter: CGPoint(x: X, y: Y), radius: arcRadius,
            startAngle: CGFloat(-M_PI_2), endAngle: CGFloat(M_PI*1.5),
            clockwise: true).CGPath
        self.addOval(circleWeight, path: barPath, strokeStart: 0, strokeEnd: percent,
            strokeColor: color, fillColor: UIColor.clearColor(),
            shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
        
        // 进度条起点圆头
        let startPath = UIBezierPath(ovalInRect: CGRectMake(X-circleWeight/2,
            Y-arcRadius-circleWeight/2, circleWeight, circleWeight)).CGPath
        self.addOval(0.0, path: startPath, strokeStart: 0, strokeEnd: 1.0,
            strokeColor: color, fillColor: color,
            shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
        
        // 进度条终点圆头
        let endDotPoint = calcCircleCoordinateWithCenter(CGPoint(x: X, y: Y),
            radius: arcRadius, angle: -percent*360+90)
        let endDotPath = UIBezierPath(ovalInRect: CGRectMake(endDotPoint.x-circleWeight/2,
            endDotPoint.y-circleWeight/2, circleWeight, circleWeight)).CGPath
        self.addOval(0.0, path: endDotPath, strokeStart: 0, strokeEnd: 1.0,
            strokeColor: color, fillColor: color,
            shadowRadius: 5.0, shadowOpacity: 0.5, shadowOffsset: CGSizeZero)
        
        // 进度条遮罩1(圆弧)
        let barMaskPath = UIBezierPath(arcCenter: CGPoint(x: X, y: Y), radius: arcRadius,
            startAngle: CGFloat(-M_PI_2), endAngle: CGFloat(M_PI*1.5),
            clockwise: true).CGPath
        self.addOval(circleWeight, path: barMaskPath,
            strokeStart: percent/6, strokeEnd: percent,
            strokeColor: color, fillColor: UIColor.clearColor(),
            shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
        // 进度条遮罩2(圆)
        if percent < 0.5{
            self.addOval(0.0, path: startPath, strokeStart: 0, strokeEnd: 1.0,
                strokeColor: color, fillColor: color,
                shadowRadius: 0, shadowOpacity: 0, shadowOffsset: CGSizeZero)
        }
    }
    
    //计算圆弧上点的坐标
    func calcCircleCoordinateWithCenter(center:CGPoint, radius:CGFloat, angle:CGFloat)
        -> CGPoint {
            let x2 = radius*CGFloat(cosf(Float(angle)*Float(M_PI)/Float(180)));
            let y2 = radius*CGFloat(sinf(Float(angle)*Float(M_PI)/Float(180)));
            return CGPointMake(center.x+x2, center.y-y2);
    }
    
    //添加圆弧
    func addOval(lineWidth: CGFloat, path: CGPathRef, strokeStart: CGFloat,
        strokeEnd: CGFloat, strokeColor: UIColor, fillColor: UIColor,
        shadowRadius: CGFloat, shadowOpacity: Float, shadowOffsset: CGSize) {
            
            let arc = CAShapeLayer()
            arc.lineWidth = lineWidth
            arc.path = path
            arc.strokeStart = strokeStart
            arc.strokeEnd = strokeEnd
            arc.strokeColor = strokeColor.CGColor
            arc.fillColor = fillColor.CGColor
            arc.shadowColor = UIColor.blackColor().CGColor
            arc.shadowRadius = shadowRadius
            arc.shadowOpacity = shadowOpacity
            arc.shadowOffset = shadowOffsset
            layer.addSublayer(arc)
    }
}
源码下载:hangge_1021.zip
评论2
  • 2楼
    2016-03-01 15:06
    1

    不需要旋转,谢谢了。

    站长回复

    好的,我下周会写篇相关的文章,你可以关注下。

  • 1楼
    2016-02-25 17:04
    1

    航哥,你好,请问下如果想做示例中的一个圆环,只是圆环从0到persent为0.5(或者其它值)的时候加动画,并且加一张图片跟着这个动画的路径从0走,该怎么做呢?我现在用UIView的animation动画改变arc.strokeEnd可以实现圆环的行走动画,但是UIImageView的动画加上去很麻烦也无法跟圆环的头同步走。

    站长回复

    图片移动的时候需要旋转吗,如果只要移动的话使用沿曲线轨迹的动画即可。下周看下有没有时间写个样例,来不及的话要下下周了。