動畫
最近接到一個需求,需要做一個啟動的加載動畫,如下圖:
load.gif
思考下,可以拆分幾個部分
動畫拆分
- 1 . 中間圓圈的旋轉動畫!
- 2 . 兩邊的畫線軌跡!
- 3 . 動態變化的進度顯示!
1.中間的圓圈旋轉
我這邊使用的4張圖片,已附上:
>
02.png
03.png
juhua.png
是不是很明顯,使用圖片的好處就是可以是動畫顏色和樣式更多變!
那么怎么讓它變成旋轉的呢?其實很簡單,Apple 就已經提供給我們很好的API 以供使用!
首先聲明需要使用的圖片視圖:
/**
加載圖
*/
@property (nonatomic,strong) UIImageView * imageView1;
@property (nonatomic,strong) UIImageView * imageView2;
@property (nonatomic,strong) UIImageView * imageView3;
@property (nonatomic,strong) UIImageView * hudImgView;
//旋轉角度
@property (nonatomic,assign) CGFloat angle1;
@property (nonatomic,assign) CGFloat angle2;
@property (nonatomic,assign) CGFloat angle3;
@property (nonatomic,assign) CGFloat angle4;
/**
是否停止加載
*/
@property (nonatomic,assign) BOOL isStopLoad;
接下來UI實現部分:
- (void)loadUI
{
CGPoint point = self.center;
CGRect frame = CGRectMake(point.x - 60, point.y - 40, 120, 120);
//背景視圖:
_bgImageView = [[UIImageView alloc]initWithFrame:self.bounds];
_bgImageView.image = [UIImage imageNamed:@"loading"];
[self addSubview:_bgImageView];
_imageView1 = [[UIImageView alloc]initWithFrame:frame];
// _imageView1.center = self.center;
_imageView1.image = [UIImage imageNamed:@"01"];
[self addSubview:_imageView1];
_imageView2 = [[UIImageView alloc]initWithFrame:frame];
// _imageView2.center = self.center;
_imageView2.image = [UIImage imageNamed:@"02"];
[self addSubview:_imageView2];
_imageView3 = [[UIImageView alloc]initWithFrame:frame];
// _imageView3.center = self.center;
_imageView3.image = [UIImage imageNamed:@"03"];
[self addSubview:_imageView3];
_hudImgView = [[UIImageView alloc]initWithFrame:frame];
// _hudImgView.center = self.center;
_hudImgView.image = [UIImage imageNamed:@"juhua"];
[self addSubview:_hudImgView];
}
最后一步,也就是關鍵的旋轉動畫,在需要開啟的地方調用如下這個方法:
ps: 旋轉角度和旋轉速度可以根據需要自己進行更改!
/**
旋轉動畫
*/
- (void)startAnimation
{
//選擇動畫:
CGAffineTransform endAngle1 = CGAffineTransformMakeRotation(_angle1 * (M_PI / 180.0f));
CGAffineTransform endAngle2 = CGAffineTransformMakeRotation(_angle2 * (M_PI / 180.0f));
CGAffineTransform endAngle3 = CGAffineTransformMakeRotation(_angle3 * (M_PI / 180.0f));
CGAffineTransform endAngle4 = CGAffineTransformMakeRotation(_angle4 * (M_PI / 180.0f));
dispatch_async(dispatch_get_main_queue(), ^{
[UIView animateWithDuration:0.01 delay:0 options:UIViewAnimationOptionCurveLinear animations:^{
_imageView1.transform = endAngle1;
_imageView2.transform = endAngle2;
_imageView3.transform = endAngle3;
_hudImgView.transform = endAngle4;
} completion:^(BOOL finished) {
_angle1 -= 4;
_angle2 += 4;
_angle3 -= 4;
_angle4 += 4;
if (!_isStopLoad) {
[self startAnimation];
}
}];
});
}
2.進度動態顯示:
這個就不再贅述,直接上代碼:
- (void)loadUI
{
//進度顯示Lable
_progressLable = [[UILabel alloc]initWithFrame:CGRectMake(0, 0, 50, 50)];
_progressLable.center = _hudImgView.center;
_progressLable.textColor = CenterColor;
_progressLable.textAlignment = NSTextAlignmentCenter;
_progressLable.font = [UIFont boldSystemFontOfSize:12];
_progressLable.layer.cornerRadius = CGRectGetWidth(_progressLable.frame)/2;
_progressLable.layer.masksToBounds = YES;
_progressLable.layer.borderColor = CenterColor.CGColor;
_progressLable.layer.borderWidth = 0.8f;
_progressLable.text = @"0%";
[self addSubview:_progressLable];
}
關于進度我這里因為Demo原因,使用的假數據,用的隨機數!
/**
進度顯示
*/
- (void)startProgressAnimation
{
if (_isStopLoad == YES) {
return;
}
//隨機數
_progressNumber += rand()%20;
if (_progressNumber >=100)
{
_progressNumber = 100;
}
_progressLable.text = [NSString stringWithFormat:@"%ld%@",_progressNumber,@"%"];
}
最后一個,前言說到的畫線軌跡動畫!
很明顯,動畫軌跡來看,一個直線和一個半圓,
既然如此,那么就可以按照這個想法來進行實現!我們都知道,OC中有個很強大的類,UIBezierPath
軌跡畫線!
可供參考的 :
UIBezierPath蘋果官方API文獻
簡書李國安的文章
下面就是代碼實現部分,先貼代碼:
-(void)drawRect:(CGRect)rect
{
//上半部軌跡:
UIBezierPath * path = [UIBezierPath bezierPath];
//起點
[path moveToPoint:CGPointMake(ScreenWidth, _hudImgView.center.y)];
//直線終點
[path addLineToPoint:CGPointMake(self.center.x+60, _hudImgView.center.y)];
//圓路徑
[path addArcWithCenter:_hudImgView.center radius:60.0f startAngle:M_PI*2 endAngle:M_PI*1 clockwise:NO];
//創建一個CAShapeLayer
CAShapeLayer * caShapelayer = [CAShapeLayer layer];
caShapelayer.path = path.CGPath;
//線條寬度
caShapelayer.lineWidth = 1.5f;
caShapelayer.frame = self.bounds;
//線條顏色
caShapelayer.strokeColor = CenterColor.CGColor;
//填充顏色
caShapelayer.fillColor = [UIColor clearColor].CGColor;
[self.layer addSublayer:caShapelayer];
//下半部軌跡:
UIBezierPath * path2 = [UIBezierPath bezierPath];
[path2 moveToPoint:CGPointMake(0, _hudImgView.center.y)];
[path2 addLineToPoint:CGPointMake(self.center.x-60, _hudImgView.center.y)];
[path2 addArcWithCenter:_hudImgView.center radius:60.0f startAngle:M_PI*1 endAngle:M_PI*2 clockwise:NO];
//創建一個CAShapeLayer
CAShapeLayer * caShapelayer2 = [CAShapeLayer layer];
caShapelayer2.path = path2.CGPath;
//線條寬度
caShapelayer2.lineWidth = 1.5f;
caShapelayer2.frame = self.bounds;
//線條顏色
caShapelayer2.strokeColor = CenterColor.CGColor;
//填充顏色
caShapelayer2.fillColor = [UIColor clearColor].CGColor;
[self.layer addSublayer:caShapelayer2];
//開始動畫
dispatch_async(dispatch_get_global_queue(0, 0), ^{
[self drawLineAnimation:caShapelayer];
[self drawLineAnimation:caShapelayer2];
});
}
//繪制 Path軌跡
- (void)drawLineAnimation:(CALayer*)layer {
CABasicAnimation *bas = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
bas.duration = 2;
bas.delegate = self;
bas.fromValue = [NSNumber numberWithInteger:0];
bas.toValue = [NSNumber numberWithInteger:1];
[layer addAnimation:bas forKey:@"key"];
}
總體來說,上下部分軌跡,實際上是一樣的,所以就分析其中一個就可以了,首先,確定path 軌跡起點,拐點,和終點!
//起點
[path moveToPoint:CGPointMake(ScreenWidth, _hudImgView.center.y)];
//直線終點
[path addLineToPoint:CGPointMake(self.center.x+60, _hudImgView.center.y)];
//圓路徑
[path addArcWithCenter:_hudImgView.center radius:60.0f startAngle:M_PI*2 endAngle:M_PI*1 clockwise:NO];
直線路徑無需多說,注釋已經很清晰了,主要說下,半圓軌跡:
如下方法:
center
: 顧名思義就是圓的中心點,學過數學的都知道!
radius
: 圓的半徑!
startAngle
: 圓軌跡起始的弧度!
endAngle
: 圓軌跡結束的弧度!
clockwise
: 是否順時針!
- (void)addArcWithCenter:(CGPoint)center
radius:(CGFloat)radius
startAngle:(CGFloat)startAngle
endAngle:(CGFloat)endAngle
clockwise:(BOOL)clockwise;
軌跡已經給出,那么其余屬性見注釋,可以嘗試自己改動看效果!
至此所有的動畫效果都已經完成,在有需要的地方進行調用,就可以了!
ps: 不當之處還請海涵,分享以及記錄自己的代碼,還請不喜勿噴??!