扇形动画

.h文件

#import <UIKit/UIKit.h>

#import <QuartzCore/QuartzCore.h>

#import "ShanXingModel.h"

#define PI 3.14159265358979323846 

//////////////////////////////////////////////////////

// categoryButton interface

@interface categoryButton : UIButton

{

    

}

// Properties

// Methods

@end

//////////////////////////////////////////////////////

// ShanXingView interface

@interface ShanXingView : UIView

{

    //NSTimer *repeatingTimer;

    CGFloat seconds;

    NSInteger angle;

}

// Properties

@property (nonatomic, strong) ShanXingModel *shanXingModel;

@property (nonatomic, strong) CAShapeLayer *trackLayer;

@property (nonatomic, strong) UIBezierPath *trackPath;

@property (nonatomic, strong) UIBezierPath *progressPath;

@property (nonatomic, strong) UIColor *trackColor;

@property (nonatomic, strong) UIColor *progressColor;

@property (nonatomic) float progress;//0~1之间的数

@property (nonatomic) float progressWidth;

@property (nonatomic, strong) NSMutableArray *progressLayers;

@property (nonatomic, strong) UIButton *indoorAirButton;            //室内空气按钮

@property (nonatomic, strong) UIButton *outdoorAirButton;           //室外空气按钮

@property (nonatomic, strong) UIButton *roseboxStatusButton;        //滤网状态按钮

@property (nonatomic, strong) UILabel *describeLabel;               //描述框

@property (nonatomic, strong) UILabel *statusLabel;                 //状态框

@property (nonatomic, strong) UILabel *leftLabel;                   //左框

@property (nonatomic, strong) UILabel *rightLabel;                  //右框

@property (nonatomic, strong) UILabel *bottomDescribeLabel;         //底部描述框

- (id)init;

//- (void)setProgress:(float)progress animated:(BOOL)animated;

@end

.m文件

#import "ShanXingView.h"

#define TimeInterval 0.0556       //每一小格彩条所需要的时间 2/36 = 0.0556s;

#define Tag_indoorAirButton 1001

#define Tag_outdoorAirButton 1002

#define Tag_roseboxStatusButton 1003

/////////////////////////////////////////////////////////////////////////////////

//************************ categoryButton implementation **********************//

/////////////////////////////////////////////////////////////////////////////////

@implementation categoryButton

- (id)init

{

    self = [super init];

    if (self)

    {

        self.titleLabel.font = [UIFont systemFontOfSize:12];

        self.titleLabel.numberOfLines = 0;

        self.titleLabel.textAlignment = NSTextAlignmentCenter;

        self.layer.cornerRadius = 4;

        self.backgroundColor = [UIColor clearColor];

    }

    return self;

}

- (void)loadSubviews

{

}

- (void)layoutSubviews

{

    [super layoutSubviews];

    if (self.selected == YES)

    {

        self.layer.borderColor = EON_RGB(110, 166, 12).CGColor;

        self.layer.borderWidth = 1;

        self.titleLabel.textColor = EON_RGB(110, 166, 12);

    }

    else

    {

        self.layer.borderColor = [UIColor whiteColor].CGColor;

        self.layer.borderWidth = 0;

        self.titleLabel.textColor = [UIColor whiteColor];

    }

}

@end

/////////////////////////////////////////////////////////////////////////////////

//************************ ShanXingView implementation ************************//

/////////////////////////////////////////////////////////////////////////////////

@implementation ShanXingView

- (id)init

{

    self = [super init];

    if (self)

    {

        seconds = 0.0;

        angle = - 57;

        _progressLayers = [NSMutableArray array];

        [self loadSubviews];

    }

    return self;

}

- (void)loadSubviews

{

    if (!self.trackLayer)

    {

        self.trackLayer = [CAShapeLayer new];

        [self.layer addSublayer:self.trackLayer];

        self.trackLayer.fillColor = nil;

        self.trackLayer.frame = self.bounds;

    }

    

    if (self.progressLayers.count == 0)

    {

        for (int i = 0; i < 36; i ++)

        {

            CAShapeLayer *progressLayer = [CAShapeLayer new];

            [self.layer addSublayer:progressLayer];

            progressLayer.lineCap = kCALineCapButt;

            progressLayer.frame = self.bounds;

            progressLayer.borderWidth = 3;

            progressLayer.borderColor = [UIColor redColor].CGColor;

            [self.progressLayers addObject:progressLayer];

            progressLayer.hidden = YES;//先隐藏所有彩条

        }

    }

    if (!self.indoorAirButton)

    {

        self.indoorAirButton = [[categoryButton alloc] init];

        self.indoorAirButton.tag = Tag_indoorAirButton;

        [self addSubview:self.indoorAirButton];

        [self.indoorAirButton addTarget:self action:@selector(categoryButtonAction:) forControlEvents:UIControlEventTouchUpInside];

    }

    

    if (!self.outdoorAirButton)

    {

        self.outdoorAirButton = [[categoryButton alloc] init];

        self.outdoorAirButton.tag = Tag_outdoorAirButton;

        [self addSubview:self.outdoorAirButton];

        [self.outdoorAirButton addTarget:self action:@selector(categoryButtonAction:) forControlEvents:UIControlEventTouchUpInside];

    }

    

    if (!self.roseboxStatusButton)

    {

        self.roseboxStatusButton = [[categoryButton alloc] init];

        self.roseboxStatusButton.tag = Tag_roseboxStatusButton;

        [self addSubview:self.roseboxStatusButton];

        [self.roseboxStatusButton addTarget:self action:@selector(categoryButtonAction:) forControlEvents:UIControlEventTouchUpInside];

    }

    

    if (!self.describeLabel)

    {

        self.describeLabel = [[UILabel alloc] init];

        self.describeLabel.font = [UIFont systemFontOfSize:12];

        self.describeLabel.textColor = [UIColor whiteColor];

        self.describeLabel.textAlignment = NSTextAlignmentCenter;

        [self addSubview:self.describeLabel];

    }

    

    if (!self.statusLabel)

    {

        self.statusLabel = [[UILabel alloc] init];

        self.statusLabel.font = [UIFont boldSystemFontOfSize:24];

        self.statusLabel.textColor = [UIColor whiteColor];

        self.statusLabel.textAlignment = NSTextAlignmentCenter;

        [self addSubview:self.statusLabel];

    }

    

    if (!self.bottomDescribeLabel)

    {

        self.bottomDescribeLabel = [[UILabel alloc] init];

        self.bottomDescribeLabel.font = [UIFont systemFontOfSize:12];

        self.bottomDescribeLabel.textColor = [UIColor whiteColor];

        self.bottomDescribeLabel.textAlignment = NSTextAlignmentCenter;

        [self addSubview:self.bottomDescribeLabel];

    }

    if (!self.leftLabel)

    {

        self.leftLabel = [[UILabel alloc] init];

        self.leftLabel.font = [UIFont systemFontOfSize:12];

        self.leftLabel.textColor = [UIColor whiteColor];

        self.leftLabel.textAlignment = NSTextAlignmentCenter;

        //self.leftLabel.backgroundColor = [UIColor orangeColor];

        [self addSubview:self.leftLabel];

    }

    

    if (!self.rightLabel)

    {

        self.rightLabel = [[UILabel alloc] init];

        self.rightLabel.font = [UIFont systemFontOfSize:12];

        self.rightLabel.textColor = [UIColor whiteColor];

        self.rightLabel.numberOfLines = 0;

        self.rightLabel.textAlignment = NSTextAlignmentCenter;

        [self addSubview:self.rightLabel];

    }

}

- (void)setShanXingModel:(ShanXingModel *)shanXingModel

{

    _shanXingModel = shanXingModel;

    

    [self.indoorAirButton setTitle:[NSString stringWithFormat:@"%@ %lld",@"室内空气", _shanXingModel.indoorAir] forState:UIControlStateNormal];

    [self.outdoorAirButton setTitle:[NSString stringWithFormat:@"%@ %lld",@"室外空气",_shanXingModel.outdoorAir] forState:UIControlStateNormal];

    [self.roseboxStatusButton setTitle:[NSString stringWithFormat:@"%@ %lld%%",@"滤网状态",_shanXingModel.roseboxStatus] forState:UIControlStateNormal];

    self.describeLabel.text = @"室内空气品质";

    self.statusLabel.text = @"很好";

    

    NSDateFormatter* formatter = [[NSDateFormatter alloc] init];

    [formatter setDateFormat:@"HH:mm"];

    NSString *str = [formatter stringFromDate:_shanXingModel.startDate];

    self.bottomDescribeLabel.text = [NSString stringWithFormat:@"初始运转%@   初始粉尘%lldμg/m³",str,_shanXingModel.startDust];

    

    self.leftLabel.text = @"0";

    self.rightLabel.text = [NSString stringWithFormat:@"%@ μg/m³",@"300"];

}

- (void)layoutSubviews

{

    [super layoutSubviews];

    

    [self.indoorAirButton setFrame:CGRectMake(self.center.x - 130, 200, 60, 35)];

    [self.outdoorAirButton setFrame:CGRectMake(self.center.x - 30, 200, 60, 35)];

    [self.roseboxStatusButton setFrame:CGRectMake(self.center.x + 70, 200, 60, 35)];

    self.describeLabel.frame = CGRectMake(self.frame.size.width / 2 - 40, 130, 80, 20);

    self.statusLabel.frame = CGRectMake(self.frame.size.width / 2 - 40, 150, 80, 40);

    self.bottomDescribeLabel.frame = CGRectMake(10, 240, self.frame.size.width - 20, 20);

    self.leftLabel.frame = CGRectMake(self.center.x - 100, 90, 40, 50);

    self.rightLabel.frame = CGRectMake(self.center.x + 60, 90, 80, 50);

    

    _trackPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.center.x, 150) radius:90 startAngle: M_PI * 6 / 5 endAngle:M_PI * 9 / 5 clockwise:YES];;

    _trackLayer.path = _trackPath.CGPath;

    

    for (int i = 0; i < _progressLayers.count; i ++)

    {

        CAShapeLayer *progressLayer = _progressLayers[i];

        _progressPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(self.center.x, 150) radius:90 startAngle:M_PI * 6 / 5 + (M_PI / 60 * i) endAngle:M_PI * 73 / 60 + (M_PI / 60 * i) clockwise:YES];

        progressLayer.path = _progressPath.CGPath;

    }

}

// 覆盖drawRect方法,你可以在此自定义绘画和动画

- (void)drawRect:(CGRect)rect

{

    //UIGraphicsBeginImageContextWithOptions(CGSize size, BOOL opaque, CGFloat scale)

    UIGraphicsBeginImageContextWithOptions(CGSizeMake(14,140), NO, 1);//画图的背景框架

    CGContextRef con = UIGraphicsGetCurrentContext();

    

    CGContextSetFillColorWithColor(con, [[UIColor whiteColor] CGColor]);

    CGContextMoveToPoint(con,0, 10);//三角形框架

    CGContextAddLineToPoint(con, 14, 10);

    CGContextAddLineToPoint(con, 7, 19);

    CGContextFillPath(con);

    

    UIImage* im = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    con = UIGraphicsGetCurrentContext();

    //[im drawAtPoint:CGPointMake(100,0)];//起点坐标

    

    CGContextTranslateCTM(con, self.center.x, 150);

    CGContextRotateCTM(con, angle * M_PI/180.0);

    CGContextTranslateCTM(con, -self.center.x, - 150);

    [im drawAtPoint:CGPointMake(self.center.x,0)];

}

- (void)setTrack

{

//    _trackPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(160, 150) radius:90 startAngle: M_PI * 6 / 5 endAngle:M_PI * 9 / 5 clockwise:YES];;

//    _trackLayer.path = _trackPath.CGPath;

}

- (void)setProgress

{

//    for (int i = 0; i < _progressLayers.count; i ++)

//    {

//        CAShapeLayer *progressLayer = _progressLayers[i];

//        _progressPath = [UIBezierPath bezierPathWithArcCenter:CGPointMake(160, 150) radius:90 startAngle:M_PI * 6 / 5 + (M_PI / 60 * i) endAngle:M_PI * 73 / 60 + (M_PI / 60 * i) clockwise:YES];

//        progressLayer.path = _progressPath.CGPath;

//    }

}

- (void)setProgressWidth:(float)progressWidth

{

    _progressWidth = progressWidth;

    for (int i = 0; i < _progressLayers.count; i ++)

    {

        CAShapeLayer *progressLayer = _progressLayers[i];

        progressLayer.lineWidth = _progressWidth;

        [self setProgress];

    }

    _trackLayer.lineWidth = _progressWidth;

    

//    [self setTrack];

//    [self setProgress];

}

- (void)setTrackColor:(UIColor *)trackColor

{

    _trackLayer.strokeColor = trackColor.CGColor;

}

- (void)setProgressColor:(UIColor *)progressColor

{

    for (int i = 0; i < _progressLayers.count; i ++)

    {

        CAShapeLayer *progressLayer = _progressLayers[i];

        if (i < 4)

            progressLayer.strokeColor = EON_RGB(143, 255, 140).CGColor;

        else if (i < 8)

            progressLayer.strokeColor = EON_RGB(52, 255, 6).CGColor;

        else if (i < 12)

            progressLayer.strokeColor = EON_RGB(46, 202, 4).CGColor;

        else if (i < 16)

            progressLayer.strokeColor = EON_RGB(255, 255, 11).CGColor;

        else if (i < 20)

            progressLayer.strokeColor = EON_RGB(255, 199, 9).CGColor;

        else if (i < 24)

            progressLayer.strokeColor = EON_RGB(254, 136, 8).CGColor;

        else if (i < 28)

            progressLayer.strokeColor = EON_RGB(253, 74, 82).CGColor;

        else if (i < 32)

            progressLayer.strokeColor = EON_RGB(253, 0, 6).CGColor;

        else if (i < 36)

            progressLayer.strokeColor = EON_RGB(134, 0, 3).CGColor;

        else

            progressLayer.strokeColor = EON_RGB(3, 1, 111).CGColor;

    }

}

- (IBAction)categoryButtonAction:(UIButton *)sender

{

    //清除原来选中的状态

    for (int i = 0; i < 3; i++)

    {

        //遍历所有按钮

        categoryButton *button = (categoryButton *)[self viewWithTag:i + Tag_indoorAirButton];

        button.selected = NO;

    }

    //设置按钮状态

    sender.selected = YES;

    

    //隐藏所有彩条

    for (int i = 0; i < _progressLayers.count; i ++)

    {

        CAShapeLayer *progressLayer = _progressLayers[i];

        progressLayer.hidden = YES;

    }

    

    seconds = 0.0;

    switch (sender.tag)

    {

        case Tag_indoorAirButton:

        {

            angle = - 57;

            [NSTimer scheduledTimerWithTimeInterval: TimeInterval target:self selector:@selector(timerAction:) userInfo:nil repeats:YES];

            [self resetValue:sender];

        }

            break;

        case Tag_outdoorAirButton:

        {

            angle = - 57;

            [NSTimer scheduledTimerWithTimeInterval: TimeInterval target:self selector:@selector(timerAction1:) userInfo:nil repeats:YES];

            [self resetValue:sender];

        }

            break;

        case Tag_roseboxStatusButton:

            angle = 53;

            [NSTimer scheduledTimerWithTimeInterval: TimeInterval target:self selector:@selector(timerAction2:) userInfo:nil repeats:YES];

            [self resetValue:sender];

            break;

        default:

            break;

    }

}

- (IBAction)timerAction:(NSTimer *)timer

{

    if (seconds >= 2)

    {

        [timer invalidate];

        self.indoorAirButton.userInteractionEnabled = YES;

        self.outdoorAirButton.userInteractionEnabled = YES;

        self.roseboxStatusButton.userInteractionEnabled = YES;

    }

    else

    {

        self.indoorAirButton.userInteractionEnabled = NO;

        self.outdoorAirButton.userInteractionEnabled = NO;

        self.roseboxStatusButton.userInteractionEnabled = NO;

        seconds += TimeInterval;

        int times = seconds/TimeInterval;   //计时次数

        if (times < _shanXingModel.indoorProgress +  1)

        {

            angle += 3;

            [self setNeedsDisplay];

        }

        for (int i = 0; i < _shanXingModel.indoorProgress; i ++)

        {

            CAShapeLayer *progressLayer = _progressLayers[i];   //根据需要显示部分彩条

            if (i <= times)

                progressLayer.hidden = NO;

            else

                progressLayer.hidden = YES;

        }

    }

}

- (IBAction)timerAction1:(NSTimer *)timer

{

    if (seconds >= 2)

    {

        [timer invalidate];

        self.indoorAirButton.userInteractionEnabled = YES;

        self.outdoorAirButton.userInteractionEnabled = YES;

        self.roseboxStatusButton.userInteractionEnabled = YES;

    }

    else

    {

        self.indoorAirButton.userInteractionEnabled = NO;

        self.outdoorAirButton.userInteractionEnabled = NO;

        self.roseboxStatusButton.userInteractionEnabled = NO;

        seconds += TimeInterval;

        int times = seconds/TimeInterval;   //计时次数

        if (times < _shanXingModel.outdoorProgress + 1)

        {

            angle += 3;

            [self setNeedsDisplay];

        }

        for (int i = 0; i < _shanXingModel.outdoorProgress; i ++)

        {

            CAShapeLayer *progressLayer = _progressLayers[i];   //根据需要显示部分彩条

            if (i <= times)

                progressLayer.hidden = NO;

            else

                progressLayer.hidden = YES;

        }

    }

}

- (IBAction)timerAction2:(NSTimer *)timer

{

    if (seconds >= 2)

    {

        [timer invalidate];

        self.indoorAirButton.userInteractionEnabled = YES;

        self.outdoorAirButton.userInteractionEnabled = YES;

        self.roseboxStatusButton.userInteractionEnabled = YES;

    }

    else

    {

        self.indoorAirButton.userInteractionEnabled = NO;

        self.outdoorAirButton.userInteractionEnabled = NO;

        self.roseboxStatusButton.userInteractionEnabled = NO;

        seconds += TimeInterval;

        int times = seconds/TimeInterval;   //计时次数

        if (times < _shanXingModel.roseboxProgress + 1)

        {

            angle -= 3;

            [self setNeedsDisplay];

        }

        for (int i = 35; i >= (36 - _shanXingModel.roseboxProgress); i --)

        {

            CAShapeLayer *progressLayer = _progressLayers[i];   //根据需要显示部分彩条

            if ((35 - i) <= times)

                progressLayer.hidden = NO;

            else

                progressLayer.hidden = YES;

        }

    }

}

////停止

//- (void)releaseTimer

//{

//    if (repeatingTimer)

//    {

//        if ([repeatingTimer respondsToSelector:@selector(isValid)])

//        {

//            if ([repeatingTimer isValid])

//            {

//                [repeatingTimer invalidate];

//            }

//        }

//    }

//}

- (IBAction)resetValue:(UIButton *)sender

{

    switch (sender.tag)

    {

        case Tag_indoorAirButton:

            self.describeLabel.text = @"室内空气品质";

//            self.statusLabel.text = @"很好";

            self.statusLabel.text = _shanXingModel.indoorProgress > 24 ? @"不良" : (_shanXingModel.indoorProgress > 12 ? @"普通" : @"很好");

            self.rightLabel.text = [NSString stringWithFormat:@"%@ μg/m³",@"300"];

            break;

        case Tag_outdoorAirButton:

            self.describeLabel.text = @"室外空气品质";

            self.statusLabel.text = _shanXingModel.outdoorProgress > 24 ? @"不良" : (_shanXingModel.outdoorProgress > 12 ? @"普通" : @"很好");

            self.rightLabel.text = [NSString stringWithFormat:@"%@ PM2.5浓度 μg/m³",@"300"];

            break;

        case Tag_roseboxStatusButton:

            self.describeLabel.text = @"HEPA滤网";

            self.statusLabel.text = [NSString stringWithFormat:@"%ld天",125 * _shanXingModel.roseboxProgress / 36];

            self.rightLabel.text = @"100%";

            break;

        default:

            break;

    }

}

- (void)setProgress:(float)progress

{

//    _progress = progress;

//    

//    [self setProgress];

}

- (void)setProgress:(float)progress animated:(BOOL)animated

{

    _progress = 0.4;

    animated = YES;

    

    [self setProgress];

}

@end

原文地址:https://www.cnblogs.com/zhouwenwen/p/iOS.html