iOS動畫系列一

前言:做相關(guān)demo動畫已經(jīng)有一段時間了、現(xiàn)在閑下來記錄下相關(guān)動畫制作工猜。iOS動畫主要就是路徑動畫米诉、幀動畫、縮放動畫篷帅、以及這些動畫的組合叫組合動畫史侣。另外還有一些3D動畫和轉(zhuǎn)場動畫拴泌。不想看原理的直接下載demo使用方式很簡單。

搖桿(手柄)制作

首先需要繪制搖桿的范圍我這畫了一個圓形惊橱、然后監(jiān)聽用戶的手勢蚪腐、根據(jù)手勢移動的前后位置判斷移動的方向上、下税朴、左回季、右。此外如果你規(guī)定用戶只能上下或者左右移動正林、不能斜角移動泡一、你可以根據(jù)移動的位置判斷當(dāng)前點和中心點這條直線的斜率偏移不能超過多少度。
效果如下:


handshank.gif

1.繪制背景邊界圓

CGContextRef context = UIGraphicsGetCurrentContext();
//     CGContextSetRGBFillColor (context,  1, 0, 0, 1.0);//設(shè)置填充顏色
   CGContextSetRGBStrokeColor(context,143/255.0,190/255.0,81/255.0,1.0);//畫筆線的顏色
   CGContextSetLineWidth(context, 2.0);//線的寬度
   bigRadius = LL_mmWidth(self)/2.0-4;
   CGContextAddArc(context, LL_mmWidth(self)/2.0, LL_mmHeight(self)/2.0, bigRadius, 0, 2*PI, 0); //添加一個圓
   CGContextDrawPath(context, kCGPathStroke); //繪制路徑

2.繪制中間搖桿圓和四個方向標志以及添加搖桿手勢監(jiān)聽觅廓。

-(void)createCenterCircle:(CGRect)selfFrame
{
   //中間搖桿圓
   _centerView = [[UIView alloc]init];
   _centerView.frame = CGRectMake((CGRectGetWidth(selfFrame)-CGRectGetWidth(selfFrame)/3.0)/2.0, (CGRectGetHeight(selfFrame)-CGRectGetHeight(selfFrame)/3.0)/2.0, CGRectGetWidth(selfFrame)/3.0, CGRectGetHeight(selfFrame)/3.0);
   _handShankOriginCenter = _centerView.center;
   smallRadius = (CGRectGetWidth(selfFrame)/3.0)/2.0;
   _centerView.layer.cornerRadius = smallRadius;
   _centerView.layer.masksToBounds = YES;
   _centerView.alpha = 0.8;
   
   _centerView.backgroundColor = [UIColor colorWithRed:143/255.0 green:190/255.0 blue:81/255.0 alpha:1.0];
   [self addSubview:_centerView];
   //四個方向標志
   float interval = (CGRectGetHeight(selfFrame)-LL_mmHeight(_centerView))/4.0;
   for (int i = 0; i<4; i++) {
       UIImageView *arrow = [self InsertImageView:self cgrect:CGRectMake(0, 0, 20*FIT_WIDTH, 12*FIT_WIDTH) image:[UIImage imageNamed:self.handShankArrows[i]]];
//        InsertImageView(self, CGRectMake(0, 0, 20*FIT_WIDTH, 12*FIT_WIDTH), [UIImage imageNamed:self.handShankArrows[i]]);
//        arrow.hidden = YES;//注意隱藏箭頭了
       switch (i) {
           case 0:
           {
               //上
                arrow.center = CGPointMake(CGRectGetWidth(selfFrame)/2.0, interval);
               
           }
               break;
           case 1:
               //下
               arrow.center = CGPointMake(CGRectGetWidth(selfFrame)/2.0, CGRectGetHeight(selfFrame)-interval);
               break;
           case 2:
               //左
               arrow.frame = CGRectMake(0, 0, 12*FIT_WIDTH, 20*FIT_WIDTH);
               arrow.center = CGPointMake(interval, CGRectGetHeight(selfFrame)/2.0);
               break;
           case 3:
               //右
               arrow.frame = CGRectMake(0, 0, 12*FIT_WIDTH, 20*FIT_WIDTH);
               arrow.center = CGPointMake(CGRectGetWidth(selfFrame)-interval, CGRectGetHeight(selfFrame)/2.0);
               break;
               
           default:
               break;
       }
       
       
       
   }
  
   //搖桿添加移動手勢
   UIPanGestureRecognizer *pangesture = [[UIPanGestureRecognizer alloc]initWithTarget:self action:@selector(pangestureAction:)];
   [_centerView addGestureRecognizer:pangesture];
}

3.分析手勢數(shù)據(jù)根據(jù)上一次移動的點和這次的做比較判斷移動方向

-(void)pangestureAction:(UIPanGestureRecognizer *)recognizer
{
   CGPoint translation = [recognizer translationInView:self];
   [recognizer setTranslation:CGPointZero inView:self];
   CGPoint movingPosition = CGPointMake(recognizer.view.center.x + translation.x,
                                   recognizer.view.center.y + translation.y);
   
   int rangeRadius = bigRadius - smallRadius;
   if ([self isInciclelPoint:movingPosition andR:rangeRadius centrePoing:_handShankOriginCenter]) {
       _lasrtPoint = movingPosition;
       _centerView.center = _lasrtPoint;
       
       if (_lasrtPoint.y < _startPoint.y && (fabsf((float)(_lasrtPoint.y - _startPoint.y)) > fabs(_lasrtPoint.x - _startPoint.x))) {
           //上
           if (_currentDirection == HandShankDirectionUnknow) {
               NSLog(@"開始上");
               _currentDirection = HandShankDirectionStartTop;
           }else{
               NSLog(@"上");
               _currentDirection = HandShankDirectionTop;
           }
          
       }else if (_lasrtPoint.y > _startPoint.y && (fabsf((float)(_lasrtPoint.y - _startPoint.y)) > fabs(_lasrtPoint.x - _startPoint.x)))
       {
           if (_currentDirection == HandShankDirectionUnknow) {
               NSLog(@"開始下");
               _currentDirection = HandShankDirectionStartDown;
           }else{
               NSLog(@"下");
               _currentDirection = HandShankDirectionDown;
           }
           
       }else if (_lasrtPoint.x >_startPoint.x && (fabsf((float)(_lasrtPoint.x -_startPoint.x)) > fabsf((float)(_lasrtPoint.y -_lasrtPoint.y))) )
       {
           if (_currentDirection == HandShankDirectionUnknow) {
               NSLog(@"開始右");
                _currentDirection = HandShankDirectionStartRight;
           }else{
               NSLog(@"右");
               _currentDirection = HandShankDirectionRight;
           }
           
       }else if (_lasrtPoint.x <_startPoint.x && (fabsf((float)(_lasrtPoint.x -_startPoint.x)) > fabsf((float)(_lasrtPoint.y -_lasrtPoint.y))) )
       {
           if (_currentDirection == HandShankDirectionUnknow) {
               NSLog(@"開始左");
               _currentDirection = HandShankDirectionStartLeft;
           }else{
               NSLog(@"左");
               _currentDirection = HandShankDirectionLeft;
           }
           
       }
       
       if (self.delegete && [self.delegete respondsToSelector:@selector(handShankDirectionDidChange:)]) {
           [self.delegete handShankDirectionDidChange:_currentDirection];
       }
   }
   
   if(recognizer.state == UIGestureRecognizerStateEnded || recognizer.state == UIGestureRecognizerStateCancelled || recognizer.state == UIGestureRecognizerStateFailed)
   {
       NSLog(@"結(jié)束");
       _startPoint = _handShankOriginCenter;
       [UIView animateWithDuration:0.5 animations:^{
           _centerView.center = _handShankOriginCenter;
       }];
       _currentDirection = HandShankDirectionUnknow;
       
       
       if (self.delegete && [self.delegete respondsToSelector:@selector(handShankDirectionDidEnd)]) {
           [self.delegete handShankDirectionDidEnd];
       }
   }
  
   
   
}

餅狀圖繪制

前言:餅狀圖由三角弧組成鼻忠、弧線有起始角度和末尾角度組成、所以可以用一個mode類記錄相關(guān)信息杈绸。然后繪制三角弧帖蔓。效果如下:


pichart.gif

1.弧線貝塞爾路徑寫法

-(UIBezierPath *)bezierPathStartAngle:(CGFloat)startAngle endAngle:(CGFloat)endAngle
{
    UIBezierPath *path = [UIBezierPath new];
    [path moveToPoint:_centerPoint];
    [path addArcWithCenter:_centerPoint radius:_radius startAngle:DEGREES_TO_RADIANS(startAngle) endAngle:DEGREES_TO_RADIANS(endAngle) clockwise:YES];
    [path closePath];
    return path;
}

2.生成弧線和對應(yīng)的文字

-(void)createPieChartView
{
    [self.models enumerateObjectsUsingBlock:^(CurveModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        UIBezierPath *path = [self bezierPathStartAngle:obj.startAngel endAngle:obj.endAngel];
        CAShapeLayer *trangleLayer = [CAShapeLayer layer];
        //        maskLayer.backgroundColor = [UIColor purpleColor].CGColor;
        trangleLayer.path = [path CGPath];
        trangleLayer.fillColor = obj.color.CGColor;
        trangleLayer.fillRule = kCAFillRuleNonZero;//kCAFillRuleEvenOdd畫的區(qū)域 取反  解釋為奇偶。
        [self.layer addSublayer:trangleLayer];
        obj.trangleLayer = trangleLayer;
        
         CGFloat angle = obj.endAngel-(obj.endAngel-obj.startAngel)/2.0;//扇形邊緣中心位置的角度
        //扇形邊緣的中心點
//        CGPoint aPoint = CGPointMake(_centerPoint.x+ _radius*cos(DEGREES_TO_RADIANS(angle)),_centerPoint.y+ _radius*sin(DEGREES_TO_RADIANS(angle)));
        //外面邊緣的半徑
        CGFloat outRadius = [self height]/2.0+100;//100是隨意
        CGPoint outCenterPoint = CGPointMake(_centerPoint.x+ outRadius*cos(DEGREES_TO_RADIANS(angle)), _centerPoint.y+outRadius*sin(DEGREES_TO_RADIANS(angle)));
        obj.outCenterPoint = outCenterPoint;
        
        int width = 30;
        //內(nèi)部邊緣文字
        UILabel *label0 = [[UILabel alloc]init];
        label0.adjustsFontSizeToFitWidth = YES;
        label0.bounds = CGRectMake(0, 0, width, width);
        CGFloat newRadius0 = (_radius-((width/2.0)/cos(DEGREES_TO_RADIANS(45))));//扇形的半徑+label的對角線長度
        //新半徑扇形的邊緣中心點
        CGPoint bPoint0 = CGPointMake(_centerPoint.x+ newRadius0*cos(DEGREES_TO_RADIANS(angle)), _centerPoint.y+newRadius0*sin(DEGREES_TO_RADIANS(angle)));
        obj.innerLabelCenterPoint = bPoint0;
        obj.innerLabe = label0;
        label0.center = outCenterPoint;
        label0.text = @"6";
        label0.textAlignment = NSTextAlignmentCenter;
        [self addSubview:label0];
        
        
        //外圍邊緣文字
        UILabel *label = [[UILabel alloc]init];
        label.text = @"%10";
        label.textAlignment = NSTextAlignmentCenter;
        label.adjustsFontSizeToFitWidth = YES;
        label.bounds = CGRectMake(0, 0, width, width);
        CGFloat newRadius = (_radius+((width/2.0)/cos(DEGREES_TO_RADIANS(45))));//扇形的半徑+label的對角線長度
        //新半徑扇形的邊緣中心點
        CGPoint bPoint = CGPointMake(_centerPoint.x+ newRadius*cos(DEGREES_TO_RADIANS(angle)), _centerPoint.y+newRadius*sin(DEGREES_TO_RADIANS(angle)));
        obj.outLabelCenterPoint = bPoint;
        obj.outLabel=label;
        label.center = outCenterPoint; //CGPointMake( aPoint.x+width/2.0, aPoint.y+((width/2.0)*tan(DEGREES_TO_RADIANS(angle))));
        [self addSubview:label];
        
    }];
    
}

3.添加簡單翻轉(zhuǎn)動畫和路徑動畫

-(void)startAnimation
{
    //翻轉(zhuǎn) oglFlip
   [CommonUse addAnimationLayer:self.layer type:@"oglFlip"];
    
    [self.models enumerateObjectsUsingBlock:^(CurveModel * _Nonnull obj, NSUInteger idx, BOOL * _Nonnull stop) {
        [self startLabelAnimation:obj];
    }];
    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(2.1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
        [self stopAnimation];
    });
}

傳送門:

源碼
有疑問的小伙伴歡迎加交流討論QQ:206931384

喜歡的小伙伴們在我git上給個star感激不盡瞳脓、目前正在持續(xù)更新中喜歡關(guān)注的和建議小伙伴可以fork一下塑娇。你的贊美是我努力的源泉我會加油的!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末篡殷,一起剝皮案震驚了整個濱河市钝吮,隨后出現(xiàn)的幾起案子埋涧,更是在濱河造成了極大的恐慌板辽,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,454評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件棘催,死亡現(xiàn)場離奇詭異劲弦,居然都是意外死亡,警方通過查閱死者的電腦和手機醇坝,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,553評論 3 385
  • 文/潘曉璐 我一進店門邑跪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人呼猪,你說我怎么就攤上這事画畅。” “怎么了宋距?”我有些...
    開封第一講書人閱讀 157,921評論 0 348
  • 文/不壞的土叔 我叫張陵轴踱,是天一觀的道長。 經(jīng)常有香客問我谚赎,道長淫僻,這世上最難降的妖魔是什么诱篷? 我笑而不...
    開封第一講書人閱讀 56,648評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮雳灵,結(jié)果婚禮上棕所,老公的妹妹穿的比我還像新娘。我一直安慰自己悯辙,他們只是感情好琳省,可當(dāng)我...
    茶點故事閱讀 65,770評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著躲撰,像睡著了一般岛啸。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上茴肥,一...
    開封第一講書人閱讀 49,950評論 1 291
  • 那天坚踩,我揣著相機與錄音,去河邊找鬼瓤狐。 笑死瞬铸,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的础锐。 我是一名探鬼主播嗓节,決...
    沈念sama閱讀 39,090評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼皆警!你這毒婦竟也來了拦宣?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,817評論 0 268
  • 序言:老撾萬榮一對情侶失蹤信姓,失蹤者是張志新(化名)和其女友劉穎鸵隧,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體意推,經(jīng)...
    沈念sama閱讀 44,275評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡豆瘫,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,592評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了菊值。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片外驱。...
    茶點故事閱讀 38,724評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖腻窒,靈堂內(nèi)的尸體忽然破棺而出昵宇,到底是詐尸還是另有隱情,我是刑警寧澤儿子,帶...
    沈念sama閱讀 34,409評論 4 333
  • 正文 年R本政府宣布瓦哎,位于F島的核電站,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏杭煎。R本人自食惡果不足惜恩够,卻給世界環(huán)境...
    茶點故事閱讀 40,052評論 3 316
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望羡铲。 院中可真熱鬧蜂桶,春花似錦、人聲如沸也切。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,815評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽雷恃。三九已至疆股,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間倒槐,已是汗流浹背旬痹。 一陣腳步聲響...
    開封第一講書人閱讀 32,043評論 1 266
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留讨越,地道東北人两残。 一個月前我還...
    沈念sama閱讀 46,503評論 2 361
  • 正文 我出身青樓,卻偏偏與公主長得像把跨,于是被迫代替她去往敵國和親人弓。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 43,627評論 2 350

推薦閱讀更多精彩內(nèi)容

  • 1着逐、通過CocoaPods安裝項目名稱項目信息 AFNetworking網(wǎng)絡(luò)請求組件 FMDB本地數(shù)據(jù)庫組件 SD...
    陽明先生_X自主閱讀 15,969評論 3 119
  • 打掃干凈的房間崔赌,春陽剛剛好 茶香漸濃 假想誰會第一個到來 那一只麻雀已錯過列車 雙飛燕早回絕 會是誰呢 這一杯春茶...
    棟間塘閱讀 199評論 0 0
  • 今天早操送孩子上學(xué)后去上班,默默觀察自己對同事的態(tài)度耸别,和同事對我的態(tài)度健芭。想找到能夠走進同事、客戶心里的那個人太雨,我也...
    TA77范麗萍閱讀 135評論 1 2
  • 最近很多想學(xué)UI設(shè)計的小白同學(xué)來咨詢我囊扳,說現(xiàn)在那么多人學(xué)UI設(shè)計,我去學(xué) 還有前途嗎兜看? 對于這個問題根據(jù)我對這個行...
    UI設(shè)計江老師閱讀 1,308評論 0 0
  • 輕輕站立锥咸,微閉雙眼,靜靜地與自己相處细移,眼前一片黑暗搏予,世界在我心里。 我聽見海水緩緩拍打礁石弧轧,遠處的...
    紫心姐姐閱讀 724評論 0 0