【iOS】畫圈的軌跡動畫

動畫

最近接到一個需求,需要做一個啟動的加載動畫,如下圖:

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: 不當之處還請海涵,分享以及記錄自己的代碼,還請不喜勿噴??!

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子,更是在濱河造成了極大的恐慌,老刑警劉巖,帶你破解...
    沈念sama閱讀 227,663評論 6 531
  • 序言:濱河連續發生了三起死亡事件,死亡現場離奇詭異,居然都是意外死亡,警方通過查閱死者的電腦和手機,發現死者居然都...
    沈念sama閱讀 98,125評論 3 414
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事?!?“怎么了?”我有些...
    開封第一講書人閱讀 175,506評論 0 373
  • 文/不壞的土叔 我叫張陵,是天一觀的道長。 經常有香客問我,道長,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 62,614評論 1 307
  • 正文 為了忘掉前任,我火速辦了婚禮,結果婚禮上,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好,可當我...
    茶點故事閱讀 71,402評論 6 404
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發上,一...
    開封第一講書人閱讀 54,934評論 1 321
  • 那天,我揣著相機與錄音,去河邊找鬼。 笑死,一個胖子當著我的面吹牛,可吹牛的內容都是我干的。 我是一名探鬼主播,決...
    沈念sama閱讀 43,021評論 3 440
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 42,168評論 0 287
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后,有當地人在樹林里發現了一具尸體,經...
    沈念sama閱讀 48,690評論 1 333
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 40,596評論 3 354
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發現自己被綠了。 大學時的朋友給我發了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 42,784評論 1 369
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤,帶...
    沈念sama閱讀 38,288評論 5 357
  • 正文 年R本政府宣布,位于F島的核電站,受9級特大地震影響,放射性物質發生泄漏。R本人自食惡果不足惜,卻給世界環境...
    茶點故事閱讀 44,027評論 3 347
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧,春花似錦、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 34,404評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至,卻和暖如春,著一層夾襖步出監牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 35,662評論 1 280
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人。 一個月前我還...
    沈念sama閱讀 51,398評論 3 390
  • 正文 我出身青樓,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當晚...
    茶點故事閱讀 47,743評論 2 370

推薦閱讀更多精彩內容