iOS 隐式动画

修改 view 的非 root layer 的属性时会有默认动画效果(0.25秒)。

@interface CircleAction : NSObject<CAAction>
@property (nonatomic) CGFloat oldProgress;
@end

@implementation CircleAction

-(void)runActionForKey:(NSString *)event object:(id)anObject arguments:(NSDictionary *)dict
{
    CircleLayer *cLayer = (CircleLayer*)anObject;
    NSLog(@"--- B %.2f",cLayer.progress);
    
    CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
    animation.duration = 1;
    animation.fromValue = @(self.oldProgress);
    animation.toValue = @(cLayer.progress);
    animation.removedOnCompletion = NO;
    animation.fillMode = kCAFillModeForwards;
    [cLayer addAnimation:animation forKey:@"strokeEnd"];
}

@end

@interface CircleLayer()<CALayerDelegate>

@end

@implementation CircleLayer
@dynamic progress;
- (instancetype)init
{
    self = [super init];
    if (self) {
        self.delegate = self;
    }
    return self;
}

-(void)setFrame:(CGRect)frame
{
    [super setFrame:frame];
    
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path addArcWithCenter:CGPointMake(frame.size.width/2.0, frame.size.height/2.0) radius:50 startAngle:0 endAngle:M_PI*2 clockwise:NO];
    self.path = path.CGPath;
    self.fillColor = [UIColor clearColor].CGColor;
    self.strokeColor = [UIColor orangeColor].CGColor;
    self.lineWidth = 3;
    self.strokeStart = 0;
    self.strokeEnd = 1;
}


/*
 1、当 CALayer 属性发生改变时候,会调用 - (id<CAAction>)actionForKey:(NSString *)event
 2、如果 actionForKey:返回了一个 Action,不会再调用 actionForLayer:forKey:
 3、如果 actionForKey:没有返回了一个 Action,则会调用代理的 actionForLayer:forKey:
 4、actionForLayer:forKey: 返回的 id 需要实现 runActionForKey: object: arguments:。
 */
-(id<CAAction>)actionForLayer:(CALayer *)layer forKey:(NSString *)event
{
    CircleLayer *cLayer = (CircleLayer*)layer;
    NSLog(@"--- A %.2f",cLayer.progress);
    
    CircleAction *action = [[CircleAction alloc] init];
    action.oldProgress = cLayer.progress;
    
    return action;
}


@end

 

@implementation ViewController
{
    CircleLayer *_cLayer;
}

- (void)viewDidLoad {
    [super viewDidLoad];
    
    _cLayer = [[CircleLayer alloc] init];
    _cLayer.frame = CGRectMake(100, 100, 120, 120);
    _cLayer.backgroundColor = [UIColor yellowColor].CGColor;
    [self.view.layer addSublayer:_cLayer];
}

-(void)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    _cLayer.progress = 0.5;
}

@end

 

参考文章:

https://www.jianshu.com/p/9e9c8ee3f7a2

https://www.jianshu.com/p/90415eb764bf

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值