CAKeyframeAnimation

CoreAnimation入门
需求如下:

屏幕快照 2019-03-12 下午3.12.57.png

通过负载率的百分比调整箭头的角度,图一个简单,背景那个圆圈是UI提供的图片。

思路

给一个路径,然后设置其百分比就行了。

具体实现如下:

#import "ViewController.h"
#include <math.h>

@interface ViewController ()
@property (weak, nonatomic) IBOutlet UITextField *precentField;
@property (weak, nonatomic) IBOutlet UIImageView *arrowView;

@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    // Do any additional setup after loading the view, typically from a nib.
}


- (IBAction)confirmAction:(UIButton *)sender {
    [self.view endEditing:YES];
    NSString *precent = self.precentField.text;
    CGFloat precentValue = [precent floatValue];
    [self turnWithPrecent:precentValue];
}
- (void)turnWithPrecent:(CGFloat)precent{
    
    
    CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
    CGMutablePathRef path = CGPathCreateMutable();
    CGPathAddRelativeArc(path, NULL, 73, 73,55, -M_PI-(0.5*M_PI-acos(47.0/73.0)), (2*M_PI-acos(47.0/73.0)*2)*precent);

    keyframeAnimation.path = path;
//    keyframeAnimation.delegate = self;
    CGPathRelease(path);

    
    CABasicAnimation* rotationAnimation;
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
    rotationAnimation.fromValue = [NSNumber numberWithFloat: -M_PI-(0.5*M_PI-acos(47.0/73.0))];

    rotationAnimation.toValue = [NSNumber numberWithFloat: -M_PI-(0.5*M_PI-acos(47.0/73.0))+(2*M_PI-acos(47.0/73.0)*2)*precent];

    
    
    CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
    animationGroup.animations = @[keyframeAnimation,rotationAnimation];
    animationGroup.duration = 2.0*precent;
    animationGroup.fillMode = kCAFillModeForwards;
    animationGroup.removedOnCompletion = NO;
    animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear];
    [self.arrowView.layer addAnimation:animationGroup forKey:@"rotationAnimation"];

}
@property (nonatomic, strong)UIImageView *imageView;  //设备进度背景
@property (nonatomic, strong)UIImageView *deviceIcon;  //设备图片
@property (nonatomic, strong)UILabel *percentageLabel;  //百分比
@property (nonatomic, strong)UILabel *deviceRateLabel; //负载率
@property (nonatomic, nonatomic) UIImageView *arrowView;

- (void)addSubViews{
    [self addSubview:self.imageView];
    [self addSubview:self.deviceIcon];
    [self addSubview:self.percentageLabel];
    [self addSubview:self.deviceRateLabel];
    [self.imageView addSubview:self.arrowView];
}

- (void)setConstraints{
    [self.imageView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(self);
        make.top.mas_equalTo(self).mas_offset(20);
        make.height.mas_equalTo(120);
        make.width.mas_equalTo(146);
    }];
    
    [self.arrowView mas_makeConstraints:^(MASConstraintMaker *make) {
        make.top.mas_equalTo(self.imageView.mas_bottom).mas_offset(1);
        make.left.mas_equalTo(self.imageView).offset(10);
        make.height.mas_equalTo(10);
        make.width.mas_equalTo(10);
    }];
    
    [self.deviceIcon mas_makeConstraints:^(MASConstraintMaker *make) {
        make.centerX.mas_equalTo(self.imageView);
        make.centerY.mas_equalTo(self.imageView);
        make.width.mas_equalTo(50);
        make.height.mas_equalTo(50);
        
    }];
    
    [self.percentageLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(self);
        make.top.mas_equalTo(self.deviceIcon.mas_bottom).mas_offset(10);
        make.width.mas_equalTo(kSCREEN_WIDTH);
        make.height.mas_equalTo(30);
        
    }];
    
    [self.deviceRateLabel mas_makeConstraints:^(MASConstraintMaker *make) {
        make.left.mas_equalTo(self);
        make.top.mas_equalTo(self.percentageLabel.mas_bottom).mas_offset(10);;
        make.width.mas_equalTo(kSCREEN_WIDTH);
        make.height.mas_equalTo(12);
        
    }];
}

- (UIImageView *)imageView{
    return _imageView = _imageView?:[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"fmp_Path_img"]];
}

- (UIImageView *)deviceIcon{
    return _deviceIcon = _deviceIcon?:[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"fmp_device_01_img"]];
}

-(UILabel *)percentageLabel{
    if(!_percentageLabel){
        _percentageLabel = [[UILabel alloc]init];
        _percentageLabel.textColor = [UIColor colorWithHexString:@"#07C08C"];
        _percentageLabel.font = [UIFont systemFontOfSize:12];
        _percentageLabel.textAlignment = NSTextAlignmentCenter;
        
    }
    return _percentageLabel;
}

-(UILabel *)deviceRateLabel{
    if(!_deviceRateLabel){
        _deviceRateLabel = [[UILabel alloc]init];
        _deviceRateLabel.textColor = [UIColor SCTextGrayColor];
        _deviceRateLabel.font = [UIFont systemFontOfSize:12];
        _deviceRateLabel.textAlignment = NSTextAlignmentCenter;

    }
    return _deviceRateLabel;
}

- (UIImageView *)arrowView{
    return _arrowView = _arrowView?:[[UIImageView alloc] initWithImage:[UIImage imageNamed:@"fmp_path_arrowImg"]];
}

相关知识点:

1、这个需求点最核心的内容就是如何使用CAKeyframeAnimation创建一个带路径的动画效果。Path方式
1)创建动画对象进行位移

CAKeyframeAnimation *keyframeAnimation = [CAKeyframeAnimation animationWithKeyPath:@"position"];
  1. 创建一个CGPathRef对象,就是动画的路线
CGMutablePathRef path = CGPathCreateMutable();
  1. 自动沿着弧度移动
CGPathAddRelativeArc(path, NULL, 73, 73,55, -M_PI-(0.5*M_PI-acos(47.0/73.0)), (2*M_PI-acos(47.0/73.0)*2)*precent);
  1. 旋转动画
CABasicAnimation* rotationAnimation;
    rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];

5)动画组

CAAnimationGroup *animationGroup = [CAAnimationGroup animation];
animationGroup.animations = @[keyframeAnimation,rotationAnimation];    
animationGroup.duration = 2.0*precent; 
//填充效果:动画结束后,动画将保持最后的表现状态
animationGroup.fillMode = kCAFillModeForwards; 
animationGroup.removedOnCompletion = NO;
animationGroup.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionLinear]; 
[self.arrowView.layer addAnimation:animationGroup forKey:@"rotationAnimation"];

核心动画组例子

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 199,711评论 5 468
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,932评论 2 376
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 146,770评论 0 330
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,799评论 1 271
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,697评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,069评论 1 276
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,535评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,200评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,353评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,290评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,331评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,020评论 3 315
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,610评论 3 303
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,694评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,927评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,330评论 2 346
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,904评论 2 341

推荐阅读更多精彩内容