<h4>简述</h4>
今天来实现一个爱奇艺的加载动画效果,大概思路如下:
1、绘制一个三角形,并对其播放旋转两周的动画;
2、绘制一个98%的环形,首先播放正向轨迹动画,再对其播放反向轨迹动画。
<h4>效果是这样</h4>

<h4>No code no bibi</h4>
<h6>SZPlayLoadingView.h文件</h6>
#import <UIKit/UIKit.h>
@interface SZPlayTriangleView : UIView
@end
@interface SZPlayLoadingView : UIView
- (void)showLoading;
@end
<h6>SZPlayLoadingView.m文件</h6>
#import "SZPlayLoadingView.h"
static NSString * const kCircleAnimationName = @"circleAnimationEnd";
static NSString * const kCircleHideAnimationName = @"circleAnimationStart";
static NSString * const kTrangleAnimationName = @"kTrangleAnimationName";
static const CGFloat kAnimationDuration = 0.6;
@interface SZPlayTriangleView()
/** 三角形layer */
@property (nonatomic, strong) CAShapeLayer *triangleLayer;
@end
@implementation SZPlayTriangleView
- (void)layoutSubviews {
[super layoutSubviews];
[_triangleLayer removeFromSuperlayer];
_triangleLayer = nil;
[self.layer addSublayer:self.triangleLayer];
}
- (CAShapeLayer *)triangleLayer {
if (!_triangleLayer) {
// 1、创建三角形path
CGFloat width = self.frame.size.width*0.65;
CGFloat width2=width/(sqrt(3));
CGFloat centerX =self.frame.size.width/2;
CGFloat centerY =self.frame.size.width/2;
CGPoint PointA=CGPointMake(centerX+(width*(2/3.0)), centerY);
CGPoint PointB=CGPointMake(PointA.x-width, PointA.y-width2);
CGPoint PointC=CGPointMake(PointB.x, PointB.y+2*width2);
UIBezierPath *path = [UIBezierPath bezierPath];
[path moveToPoint:PointA];
[path addLineToPoint:PointB];
[path addLineToPoint:PointC];
[path closePath];
// 2、创建layer
_triangleLayer = [CAShapeLayer layer];
_triangleLayer.path = path.CGPath;
_triangleLayer.fillColor = [UIColor colorWithRed:0.52f green:0.76f blue:0.07f alpha:1.00f].CGColor;
}
return _triangleLayer;
}
@end
@interface SZPlayLoadingView()<CAAnimationDelegate>
/** Circle view */
@property (nonatomic, strong) CAShapeLayer *circleLayer;
/** Circle view aniation */
@property (nonatomic, strong) CABasicAnimation *circleLayerAnimation;
/** Circle view hide aniation */
@property (nonatomic, strong) CABasicAnimation *circleLayerHideAnimation;
/** 三角形 */
@property (nonatomic, strong) SZPlayTriangleView *triangleView;
/** 三角形动画 */
@property (nonatomic, strong) CABasicAnimation *triangleAnimation;
@end
@implementation SZPlayLoadingView
#pragma mark - Outer method
- (void)showLoading {
[self showCircle];
}
#pragma mark - Inner method
- (void)showCircle {
[_circleLayer removeAllAnimations];
[_triangleView removeFromSuperview];
[self addSubview:self.triangleView];
[self.layer addSublayer:self.circleLayer];
self.circleLayer.strokeStart = 0;
self.circleLayer.strokeEnd = 0.98;
[self.circleLayer addAnimation:self.circleLayerAnimation forKey:kCircleAnimationName];
}
- (void)hideCircle {
self.circleLayer.strokeStart = 0.98;
[self.circleLayer addAnimation:self.circleLayerHideAnimation forKey:kCircleHideAnimationName];
}
- (void)showTriangleAmimation {
[self.triangleView.layer addAnimation:self.triangleAnimation forKey:kTrangleAnimationName];
}
#pragma mark - Animation delegate
- (void)animationDidStop:(CAAnimation *)anim finished:(BOOL)flag {
if ([[anim valueForKey:@"animationName"] isEqualToString:kCircleHideAnimationName]) {
[self.triangleView.layer removeAllAnimations];
[self showCircle];
} else if ([[anim valueForKey:@"animationName"] isEqualToString:kCircleAnimationName]) {
[self showTriangleAmimation];
[self hideCircle];
}
}
#pragma mark - Property
- (CAShapeLayer *)circleLayer {
if (!_circleLayer) {
_circleLayer = [CAShapeLayer layer];
// 1、设置path
UIBezierPath *circlePath = [UIBezierPath bezierPathWithOvalInRect:self.bounds];
_circleLayer.path = circlePath.CGPath;
// 2、设置颜色
_circleLayer.fillColor = [UIColor clearColor].CGColor;
_circleLayer.strokeColor = [UIColor colorWithRed:0.52 green:0.76 blue:0.07 alpha:1].CGColor;
// 3、设置线条宽度和cap
_circleLayer.lineWidth = 1;
_circleLayer.lineCap = kCALineCapRound;
// 4、设置翻转
_circleLayer.transform = CATransform3DRotate(_circleLayer.transform, -M_PI_2, 0, 0, 1);
_circleLayer.transform = CATransform3DTranslate(_circleLayer.transform, -self.bounds.size.width, 0, 0);
}
return _circleLayer;
}
- (CABasicAnimation *)circleLayerAnimation {
if (!_circleLayerAnimation) {
_circleLayerAnimation = [CABasicAnimation animationWithKeyPath:@"strokeEnd"];
_circleLayerAnimation.fromValue = @(0);
_circleLayerAnimation.duration = kAnimationDuration;
[_circleLayerAnimation setValue:kCircleAnimationName forKey:@"animationName"];
_circleLayerAnimation.delegate = self;
}
return _circleLayerAnimation;
}
- (CABasicAnimation *)circleLayerHideAnimation {
if (!_circleLayerHideAnimation) {
_circleLayerHideAnimation = [CABasicAnimation animationWithKeyPath:@"strokeStart"];
_circleLayerHideAnimation.fromValue = @(0);
_circleLayerHideAnimation.duration = kAnimationDuration;
[_circleLayerHideAnimation setValue:kCircleHideAnimationName forKey:@"animationName"];
_circleLayerHideAnimation.delegate = self;
}
return _circleLayerHideAnimation;
}
- (SZPlayTriangleView *)triangleView {
if (!_triangleView) {
_triangleView = [SZPlayTriangleView new];
_triangleView.frame = CGRectMake(0, 0, self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
_triangleView.center = CGPointMake(self.bounds.size.width * 0.5, self.bounds.size.height * 0.5);
_triangleView.backgroundColor = [UIColor clearColor];
}
return _triangleView;
}
- (CABasicAnimation *)triangleAnimation {
if (!_triangleAnimation) {
_triangleAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.z"];
_triangleAnimation.toValue = @(M_PI * 2);
_triangleAnimation.duration = kAnimationDuration;
[_triangleAnimation setValue:kTrangleAnimationName forKey:@"animationName"];
}
return _triangleAnimation;
}
@end
网友评论