三、动画实战<一>

<h4>简述</h4>

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

<h4>效果是这样</h4>

loading.gif

<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

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • Android 自定义View的各种姿势1 Activity的显示之ViewRootImpl详解 Activity...
    passiontim阅读 176,094评论 25 709
  • 发现 关注 消息 iOS 第三方库、插件、知名博客总结 作者大灰狼的小绵羊哥哥关注 2017.06.26 09:4...
    肇东周阅读 14,623评论 4 61
  • 我本不该拥抱太过炽热的梦 比如明天 比如你
    nothingbad阅读 1,261评论 0 0
  • 每次洗衣服的时候,我总是习惯用手洗,在拿去洗衣机脱干,可能你们会觉得奇怪,为什么不放在洗衣机直接洗,因为我怕等。等...
    半夏sher阅读 2,338评论 2 3
  • 作者 | 舒凡出处 | 《公众账号: 知笔墨GO》 常常喜欢对于一些好电影,会看上好几遍,例如《肖申克救赎》,可能...
    布一日记阅读 5,144评论 1 5

友情链接更多精彩内容