ifish/Ifish/controllers/HotBar/Lib/PNChart/PNBar.m

289 lines
9.3 KiB
Objective-C
Executable File

//
// PNBar.m
// PNChartDemo
//
// Created by kevin on 11/7/13.
// Copyright (c) 2013年 kevinzhow. All rights reserved.
//
#import "PNBar.h"
#import "PNColor.h"
#import <CoreText/CoreText.h>
@interface PNBar ()
@property (nonatomic) float copyGrade;
@end
@implementation PNBar
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
if (self) {
_chartLine = [CAShapeLayer layer];
_chartLine.lineCap = kCALineCapButt;
_chartLine.fillColor = [[UIColor whiteColor] CGColor];
_chartLine.lineWidth = self.frame.size.width;
_chartLine.strokeEnd = 0.0;
self.clipsToBounds = YES;
[self.layer addSublayer:_chartLine];
self.barRadius = 2.0;
}
return self;
}
-(void)setBarRadius:(CGFloat)barRadius
{
_barRadius = barRadius;
self.layer.cornerRadius = _barRadius;
}
- (void)setGrade:(float)grade
{
_copyGrade = grade;
CGFloat startPosY = (1 - grade) * self.frame.size.height;
UIBezierPath *progressline = [UIBezierPath bezierPath];
[progressline moveToPoint:CGPointMake(self.frame.size.width / 2.0, self.frame.size.height)];
[progressline addLineToPoint:CGPointMake(self.frame.size.width / 2.0, startPosY)];
[progressline setLineWidth:1.0];
[progressline setLineCapStyle:kCGLineCapSquare];
[self addAnimationIfNeededWithProgressLine:progressline];
if (_barColor) {
_chartLine.strokeColor = [_barColor CGColor];
}
else {
_chartLine.strokeColor = [PNGreen CGColor];
}
if (_grade) {
_chartLine.path = progressline.CGPath;
if (_barColorGradientStart) {
// Add gradient
self.gradientMask.path = progressline.CGPath;
CABasicAnimation* opacityAnimation = [self fadeAnimation];
[self.textLayer addAnimation:opacityAnimation forKey:nil];
}
}else{
_chartLine.strokeEnd = 1.0;
_chartLine.path = progressline.CGPath;
// Check if user wants to add a gradient from the start color to the bar color
if (_barColorGradientStart) {
// Add gradient
self.gradientMask = [CAShapeLayer layer];
self.gradientMask.fillColor = [[UIColor clearColor] CGColor];
self.gradientMask.strokeColor = [[UIColor blackColor] CGColor];
self.gradientMask.lineWidth = self.frame.size.width;
self.gradientMask.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
self.gradientMask.path = progressline.CGPath;
CAGradientLayer *gradientLayer = [CAGradientLayer layer];
gradientLayer.startPoint = CGPointMake(0.0,0.0);
gradientLayer.endPoint = CGPointMake(1.0 ,0.0);
gradientLayer.frame = CGRectMake(0, 0, self.bounds.size.width, self.bounds.size.height);
UIColor *middleColor = [UIColor colorWithWhite:255/255 alpha:0.8];
NSArray *colors = @[
(__bridge id)self.barColor.CGColor,
(__bridge id)middleColor.CGColor,
(__bridge id)self.barColor.CGColor
];
gradientLayer.colors = colors;
[gradientLayer setMask:self.gradientMask];
[_chartLine addSublayer:gradientLayer];
self.gradientMask.strokeEnd = 1.0;
CABasicAnimation* opacityAnimation = [self fadeAnimation];
[self.textLayer addAnimation:opacityAnimation forKey:nil];
}
}
_grade = grade;
}
- (void)rollBack
{
[UIView animateWithDuration:0.3 delay:0.0 options:UIViewAnimationOptionCurveEaseOut animations: ^{
_chartLine.strokeColor = [UIColor clearColor].CGColor;
} completion:nil];
}
- (void)setBarColorGradientStart:(UIColor *)barColorGradientStart
{
// Set gradient color, remove any existing sublayer first
for (CALayer *sublayer in [_chartLine sublayers]) {
[sublayer removeFromSuperlayer];
}
_barColorGradientStart = barColorGradientStart;
[self setGrade:_grade];
}
// Only override drawRect: if you perform custom drawing.
// An empty implementation adversely affects performance during animation.
- (void)drawRect:(CGRect)rect
{
CGContextRef context = UIGraphicsGetCurrentContext();
CGContextSetFillColorWithColor(context, self.backgroundColor.CGColor);
CGContextFillRect(context, rect);
}
// add number display on the top of bar
-(CGPathRef)gradePath:(CGRect)rect
{
return nil;
}
-(CATextLayer*)textLayer
{
if (!_textLayer) {
_textLayer = [[CATextLayer alloc]init];
[_textLayer setString:@"0"];
[_textLayer setAlignmentMode:kCAAlignmentCenter];
[_textLayer setForegroundColor:[_labelTextColor CGColor]];
_textLayer.hidden = YES;
}
return _textLayer;
}
- (void) setLabelTextColor:(UIColor *)labelTextColor {
_labelTextColor = labelTextColor;
[_textLayer setForegroundColor:[_labelTextColor CGColor]];
}
-(void)setGradeFrame:(CGFloat)grade startPosY:(CGFloat)startPosY
{
CGFloat textheigt = self.bounds.size.height*self.grade;
CGFloat topSpace = self.bounds.size.height * (1-self.grade);
CGFloat textWidth = self.bounds.size.width;
[_chartLine addSublayer:self.textLayer];
[self.textLayer setFontSize:18.0];
[self.textLayer setString:[[NSString alloc]initWithFormat:@"%0.f",grade*self.maxDivisor]];
CGSize size = CGSizeMake(320,2000); //设置一个行高上限
NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:18.0]};
size = [self.textLayer.string boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size;
float verticalY ;
if (size.height>=textheigt) {
verticalY = topSpace - size.height;
} else {
verticalY = topSpace + (textheigt-size.height)/2.0;
}
[self.textLayer setFrame:CGRectMake((textWidth-size.width)/2.0,verticalY, size.width,size.height)];
self.textLayer.contentsScale = [UIScreen mainScreen].scale;
}
- (void)setIsShowNumber:(BOOL)isShowNumber{
if (isShowNumber) {
self.textLayer.hidden = NO;
[self setGradeFrame:_copyGrade startPosY:0];
}else{
self.textLayer.hidden = YES;
}
}
- (void)setIsNegative:(BOOL)isNegative{
if (isNegative) {
[self.textLayer setString:[[NSString alloc]initWithFormat:@"- %1.f",_grade*self.maxDivisor]];
CGSize size = CGSizeMake(320,2000); //设置一个行高上限
NSDictionary *attributes = @{NSFontAttributeName:[UIFont systemFontOfSize:18.0]};
size = [self.textLayer.string boundingRectWithSize:size options:NSStringDrawingUsesLineFragmentOrigin attributes:attributes context:nil].size;
CGRect frame = self.textLayer.frame;
frame.origin.x = (self.bounds.size.width - size.width)/2.0;
frame.size = size;
self.textLayer.frame = frame;
[self addRotationAnimationIfNeeded];
}
}
-(CABasicAnimation*)fadeAnimation
{
CABasicAnimation* fadeAnimation = nil;
if (self.displayAnimated) {
fadeAnimation = [CABasicAnimation animationWithKeyPath:@"opacity"];
fadeAnimation.fromValue = [NSNumber numberWithFloat:0.0];
fadeAnimation.toValue = [NSNumber numberWithFloat:1.0];
fadeAnimation.duration = 2.0;
}
return fadeAnimation;
}
-(void)addAnimationIfNeededWithProgressLine:(UIBezierPath *)progressline
{
if (self.displayAnimated) {
CABasicAnimation *pathAnimation = nil;
if (_grade) {
pathAnimation = [CABasicAnimation animationWithKeyPath:@"path"];
pathAnimation.fromValue = (id)_chartLine.path;
pathAnimation.toValue = (id)[progressline CGPath];
pathAnimation.duration = 0.5f;
pathAnimation.autoreverses = NO;
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
[_chartLine addAnimation:pathAnimation forKey:@"animationKey"];
}
else {
pathAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
pathAnimation.duration = 1.0;
pathAnimation.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
pathAnimation.fromValue = @0.0f;
pathAnimation.toValue = @1.0f;
[_chartLine addAnimation:pathAnimation forKey:@"strokeEndAnimation"];
}
[self.gradientMask addAnimation:pathAnimation forKey:@"animationKey"];
}
}
- (void)addRotationAnimationIfNeeded
{
if (self.displayAnimated) {
CABasicAnimation* rotationAnimation;
rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
rotationAnimation.toValue = [NSNumber numberWithFloat: M_PI];
[CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseInEaseOut];
rotationAnimation.duration = 0.1;
rotationAnimation.repeatCount = 0;//你可以设置到最大的整数值
rotationAnimation.cumulative = NO;
rotationAnimation.removedOnCompletion = NO;
rotationAnimation.fillMode = kCAFillModeForwards;
[self.textLayer addAnimation:rotationAnimation forKey:@"Rotation"];
}
}
@end