自定义Button animation
创建 LTNButton,继承自UIView;重写 initWithFrame:;再添加button
- (instancetype)initWithFrame:(CGRect)frame {
if (self = [super initWithFrame:frame]) {
_shapeLayer = [self drawMask:frame.size.height * 0.5];
_shapeLayer.fillColor = [UIColor clearColor].CGColor;
_shapeLayer.strokeColor = [UIColor whiteColor].CGColor;
_shapeLayer.lineWidth = 2;
[self.layer addSublayer:_shapeLayer];
_button = [UIButton buttonWithType:UIButtonTypeCustom];
_button.frame = self.bounds;
[_button setTitle:@"Z S K" forState:UIControlStateNormal];
[_button setTitleColor:[UIColor whiteColor] forState:UIControlStateNormal];
[_button addTarget:self action:@selector(buttonClick:) forControlEvents:UIControlEventTouchUpInside];
_button.titleLabel.font = [UIFont systemFontOfSize:15.f];
[self addSubview:_button];
[self.layer addSublayer:self.maskLayer];
}
return self;
}
- (CAShapeLayer *)drawMask:(CGFloat)radius {
CAShapeLayer *shapeLayer = [CAShapeLayer layer];
shapeLayer.frame = self.bounds;
shapeLayer.path = [self drawBezierPath:radius].CGPath;
return shapeLayer;
}
-(UIBezierPath *)drawBezierPath:(CGFloat)radius {
CGFloat radius_new = HEIGHT * 0.5 - 2;
CGFloat y = WIDTH - radius;
CGFloat x = radius;
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
bezierPath.lineJoinStyle = kCGLineJoinRound;
bezierPath.lineCapStyle = kCGLineCapRound;
[bezierPath addArcWithCenter:CGPointMake(y, HEIGHT * 0.5) radius:radius_new startAngle:-M_PI_2 endAngle:M_PI_2 clockwise:YES];
[bezierPath addArcWithCenter:CGPointMake(x, HEIGHT * 0.5) radius:radius_new startAngle:M_PI_2 endAngle:-M_PI_2 clockwise:YES];
[bezierPath closePath];
return bezierPath;
}
做完这些,将得到
接下来逐步添加 button 点击动画
- (void)buttonClick:(UIButton *)sender {
CAShapeLayer *circleLayer = [CAShapeLayer layer];
circleLayer.position = CGPointMake(WIDTH * 0.5, HEIGHT * 0.5);
circleLayer.fillColor = [UIColor whiteColor].CGColor;
circleLayer.path = [self drawCircleBezierPath:0].CGPath;
[self.layer addSublayer:circleLayer];
//动画:画出来的圆 radius 从 0 到 (HEIGHT - 10 * 2) * 0.5
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = 0.5;
animation.toValue = (__bridge id _Nullable)([self drawCircleBezierPath:(HEIGHT - 10 * 2) * 0.5].CGPath);
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[circleLayer addAnimation:animation forKey:@"cicrleAnimation"];
_circleLayer = circleLayer;
[self performSelector:@selector(nextAnimation) withObject:self afterDelay:animation.duration];
}
- (UIBezierPath *)drawCircleBezierPath:(CGFloat)radius {
UIBezierPath *bezierPath = [UIBezierPath bezierPath];
[bezierPath addArcWithCenter:CGPointZero radius:radius startAngle:0 endAngle:M_PI * 2 clockwise:YES];
return bezierPath;
}
圆扩大两倍 同时 变透明
- (void)nextAnimation {
_circleLayer.fillColor = [UIColor clearColor].CGColor;
_circleLayer.strokeColor = [UIColor whiteColor].CGColor;
_circleLayer.lineWidth = 10;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = 0.15;
animation.toValue = (__bridge id _Nullable)([self drawCircleBezierPath:HEIGHT - 10 * 2].CGPath);
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
CABasicAnimation *animation1 = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation1.beginTime = 0.10;
animation1.duration = 0.15;
animation1.toValue = @0;
animation1.removedOnCompletion = NO;
animation1.fillMode = kCAFillModeForwards;
CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
groupAnimation.fillMode = kCAFillModeForwards;
groupAnimation.removedOnCompletion = NO;
groupAnimation.duration = animation1.beginTime + animation1.duration;
groupAnimation.animations = @[animation, animation1];
[_circleLayer addAnimation:groupAnimation forKey:@"nextAnimation"];
[self performSelector:@selector(startMaskAnimation) withObject:self afterDelay:groupAnimation.duration];
}
添加一层半透明膜
-(CAShapeLayer *)maskLayer {
if (!_maskLayer) {
_maskLayer = [CAShapeLayer layer];
_maskLayer.opacity = 0;
_maskLayer.fillColor = [UIColor whiteColor].CGColor;
_maskLayer.path = [self drawBezierPath:WIDTH * 0.5].CGPath;
}
return _maskLayer;
}
- (void)startMaskAnimation {
_maskLayer.opacity = 0.15;
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = 0.25;
animation.toValue = (__bridge id _Nullable)([self drawBezierPath:self.frame.size.height * 0.5].CGPath);
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
[self.maskLayer addAnimation:animation forKey:@"startMaskAnimation"];
[self performSelector:@selector(dismissAnimation) withObject:self afterDelay:animation.duration];
}
layer 在中心点缩小成同高度的圆,同时透明度到0
- (void)dismissAnimation {
[self removeSubViews];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"path"];
animation.duration = 0.15;
animation.toValue = (__bridge id _Nullable)([self drawBezierPath:WIDTH * 0.5].CGPath);
animation.removedOnCompletion = NO;
animation.fillMode = kCAFillModeForwards;
CABasicAnimation *animation1 = [CABasicAnimation animationWithKeyPath:@"opacity"];
animation1.beginTime = 0.10;
animation1.duration = 0.15;
animation1.toValue = @0;
animation1.removedOnCompletion = NO;
animation1.fillMode = kCAFillModeForwards;
CAAnimationGroup *groupAnimation = [CAAnimationGroup animation];
groupAnimation.animations = @[animation,animation1];
groupAnimation.duration = animation1.beginTime + animation1.duration;
groupAnimation.removedOnCompletion = NO;
groupAnimation.fillMode = kCAFillModeForwards;
[_shapeLayer addAnimation:groupAnimation forKey:@"dismissAnimation"];
[self performSelector:@selector(loadAnimation) withObject:self afterDelay:groupAnimation.duration];
}
- (void)removeSubViews {
[_button removeFromSuperview];
[_maskLayer removeFromSuperlayer];
[_circleLayer removeFromSuperlayer];
}
模拟载入旋转动画
-(CAShapeLayer *)loadingLayer {
if (!_loadingLayer) {
_loadingLayer = [CAShapeLayer layer];
_loadingLayer.position = CGPointMake(WIDTH/2, HEIGHT/2);
_loadingLayer.fillColor = [UIColor clearColor].CGColor;
_loadingLayer.strokeColor = [UIColor whiteColor].CGColor;
_loadingLayer.lineWidth = 2;
_loadingLayer.path = [self drawLoadingBezierPath].CGPath;
}
return _loadingLayer;
}
- (UIBezierPath *)drawLoadingBezierPath {
UIBezierPath *path = [UIBezierPath bezierPath];
CGFloat radius = HEIGHT * 0.5 - 2;
[path addArcWithCenter:CGPointZero radius:radius startAngle:M_PI/2 endAngle:M_PI/2+M_PI/2 clockwise:YES];
return path;
}
- (void)loadAnimation {
[self.layer addSublayer:self.loadingLayer];
CABasicAnimation *animation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
animation.duration = 0.5;
animation.fromValue = @(0);
animation.toValue = @(M_PI * 2);
animation.repeatCount = LONG_MAX;
[self.loadingLayer addAnimation:animation forKey:@"loadAnimation"];
[self performSelector:@selector(removeAllAnimation) withObject:self afterDelay:animation.duration + 2];
}
动画结束,后续 block
- (void)removeAllAnimation {
[self removeSubViews];
[_loadingLayer removeFromSuperlayer];
if (self.translateBlock) {
self.translateBlock();
}
}