IOS貝塞爾曲線圓形進度條和加載動畫

作項目讓作一個加載動畫,一個圈圈在轉中間加一個圖片,網上有好多demo,這裏我也本身寫了一個,中間的圖片可加可不加。其中主要用到貝塞爾曲線。UIBezierPath是對CGContextRef的進一步封裝,很少說直接上代碼:ide

#import <UIKit/UIKit.h>

@interface CircleLoader : UIView

//進度顏色
@property(nonatomic, retain) UIColor* progressTintColor ;


//軌道顏色
@property(nonatomic, retain) UIColor* trackTintColor ;

//軌道寬度
@property (nonatomic,assign) float lineWidth;

//中間圖片
@property (nonatomic,strong) UIImage *centerImage;

//進度
@property (nonatomic,assign) float progressValue;

//提示標題
@property (nonatomic,strong) NSString *promptTitle;

//開啓動畫
@property (nonatomic,assign) BOOL animationing;

//隱藏消失
- (void)hide;

@end
#import "CircleLoader.h"

@interface CircleLoader ()

@property (nonatomic,strong) CAShapeLayer *trackLayer;

@property (nonatomic,strong) CAShapeLayer *progressLayer;

@end

@implementation CircleLoader

- (instancetype)initWithFrame:(CGRect)frame
{
    self = [super initWithFrame:frame];
    if (self) {
        self.backgroundColor=[UIColor clearColor];
    }
    return self;
}
-(void)drawRect:(CGRect)rect
{
    [super drawRect:rect];
    _trackLayer=[CAShapeLayer layer];
    _trackLayer.frame=CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    _trackLayer.lineWidth=_lineWidth;
    _trackLayer.strokeColor=_trackTintColor.CGColor;
    _trackLayer.fillColor = self.backgroundColor.CGColor;
    _trackLayer.lineCap = kCALineCapRound;
    [self.layer addSublayer:_trackLayer];
    
    _progressLayer=[CAShapeLayer layer];
    _progressLayer.frame=CGRectMake(0, 0, self.frame.size.width, self.frame.size.height);
    _progressLayer.lineWidth=_lineWidth;
    _progressLayer.strokeColor=_progressTintColor.CGColor;
    _progressLayer.fillColor = self.backgroundColor.CGColor;
    _progressLayer.lineCap = kCALineCapRound;
    [self.layer addSublayer:_progressLayer];
    
    if (_centerImage!=nil) {
        UIImageView *centerImgView=[[UIImageView alloc]initWithImage:_centerImage];
        centerImgView.frame=CGRectMake(_lineWidth, _lineWidth, self.frame.size.width-2*_lineWidth, self.frame.size.height-_lineWidth*2);
//        centerImgView.center=self.center;
        centerImgView.layer.cornerRadius=(self.frame.size.width+_lineWidth)/2;
        centerImgView.clipsToBounds=YES;
        [self.layer addSublayer:centerImgView.layer];
    }
    
    [self start];
}

- (void)drawBackgroundCircle:(BOOL) animationing {
    
    //貝塞爾曲線 0度是在十字右邊方向   -M_PI/2至關於在十字上邊方向
    CGFloat startAngle = - ((float)M_PI / 2); // 90 Degrees
    
    //
    CGFloat endAngle = (2 * (float)M_PI) + - ((float)M_PI / 8);;
    CGPoint center = CGPointMake(self.bounds.size.width/2, self.bounds.size.height/2);
    
    CGFloat radius = (self.bounds.size.width - _lineWidth)/2;
    
    
    UIBezierPath *processPath = [UIBezierPath bezierPath];
//    processPath.lineWidth=_lineWidth;
    
    UIBezierPath *trackPath = [UIBezierPath bezierPath];
//    trackPath.lineWidth=_lineWidth;
    
    //---------------------------------------
    // Make end angle to 90% of the progress
    //---------------------------------------
    if (!animationing) {
        endAngle = (_progressValue * 2*(float)M_PI) + startAngle;
    }
    else
    {
        endAngle = (0.1 * 2*(float)M_PI) + startAngle;
    }
    
    [processPath addArcWithCenter:center radius:radius startAngle:startAngle endAngle:endAngle clockwise:YES];
    [trackPath addArcWithCenter:center radius:radius startAngle:0 endAngle:2*M_PI clockwise:YES];
    _progressLayer.path = processPath.CGPath;
    _trackLayer.path=trackPath.CGPath;
}
- (void)start
{
    [self drawBackgroundCircle:_animationing];
    if (_animationing) {
        CABasicAnimation *rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
        rotationAnimation.toValue = [NSNumber numberWithFloat:M_PI * 2.0];
        rotationAnimation.duration = 1;
        rotationAnimation.cumulative = YES;
        rotationAnimation.repeatCount = HUGE_VALF;
        [_progressLayer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
    }
    
}
- (void)hide
{
    [_progressLayer removeAllAnimations];
    [self removeFromSuperview];
}
@end

調用:動畫

#import "ViewController.h"
#import "CircleLoader.h"

@interface ViewController ()

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
    //設置視圖大小
    CircleLoader *view=[[CircleLoader alloc]initWithFrame:CGRectMake(100, 100, 70, 70)];
    //設置軌道顏色
    view.trackTintColor=[UIColor redColor];
    //設置進度條顏色
    view.progressTintColor=[UIColor greenColor];
    //設置軌道寬度
    view.lineWidth=5.0;
     //設置進度
    view.progressValue=0.7;
    //設置是否轉到 YES進度不用設置
    view.animationing=YES;
    
    //添加中間圖片  不設置則不顯示
    view.centerImage=[UIImage imageNamed:@"yzp_loading"];
    
    //添加視圖
    [self.view addSubview:view];
    
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(5 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        //視圖隱藏
//        [view hide];
    });
    
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
    // Dispose of any resources that can be recreated.
}

@end

效果:atom

相關文章
相關標籤/搜索