扇形动画
.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:@"%@\n%lld",@"室内空气", _shanXingModel.indoorAir] forState:UIControlStateNormal];
[self.outdoorAirButton setTitle:[NSString stringWithFormat:@"%@\n%lld",@"室外空气",_shanXingModel.outdoorAir] forState:UIControlStateNormal];
[self.roseboxStatusButton setTitle:[NSString stringWithFormat:@"%@\n%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:@"%@\nμ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:@"%@\nμg/m³",@"300"];
break;
case Tag_outdoorAirButton:
self.describeLabel.text = @"室外空气品质";
self.statusLabel.text = _shanXingModel.outdoorProgress > 24 ? @"不良" : (_shanXingModel.outdoorProgress > 12 ? @"普通" : @"很好");
self.rightLabel.text = [NSString stringWithFormat:@"%@\nPM2.5浓度\nμ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