iOS利用CALayer实现动画加载的效果

 更新时间:2016年10月21日 10:35:53   投稿:daisy  
网上关于动画加载的效果大多每一个圆圈都是使用UIView,因为这种容易控制,但是这里用的是CALayer,文中给出了详细的实现示例代码,相信会对大家的学习和理解很有帮助,感兴趣的朋友们下面来一起看看吧。

首先来看看效果图

实现过程如下

控制器调用就一句代码:

[self showLoadingInView:self.view];

方便控制器如此调用,就要为控制器添加一个分类

.h文件

#import <UIKit/UIKit.h>
#import "GQCircleLoadView.h"
@interface UIViewController (GQCircleLoad)
//显示动画
- (void)showLoadingInView:(UIView*)view;
//隐藏动画
- (void)hideLoad;
@property (nonatomic,strong) GQCircleLoadView *loadingView;
@end

.m文件

#import "UIViewController+GQCircleLoad.h"
#import <objc/runtime.h>
@implementation UIViewController (GQCircleLoad)
- (GQCircleLoadView*)loadingView
{
 return objc_getAssociatedObject(self, @"loadingView");
}
- (void)setLoadingView:(GQCircleLoadView*)loadingView
{
 objc_setAssociatedObject(self, @"loadingView", loadingView, OBJC_ASSOCIATION_RETAIN_NONATOMIC);
}
- (void)showLoadingInView:(UIView*)view{
 if (self.loadingView == nil) {
  self.loadingView = [[GQCircleLoadView alloc]init];
 }
 if (view) {
  [view addSubview:self.loadingView];
  self.loadingView.frame = view.bounds;
 }else{
  UIWindow *appKeyWindow = [UIApplication sharedApplication].keyWindow;
  [appKeyWindow addSubview:self.loadingView];
  self.loadingView.frame = appKeyWindow.bounds;
 }
}
- (void)hideLoad{
 [self.loadingView removeFromSuperview];
}
@end

接下来就是GQCircleLoadView继承UIView,里面通过drawRect画出圆圈,并且动画的实现

#import "GQCircleLoadView.h"
#define WINDOW_width [[UIScreen mainScreen] bounds].size.width
#define WINDOW_height [[UIScreen mainScreen] bounds].size.height
static NSInteger circleCount = 3;
static CGFloat cornerRadius = 10;
static CGFloat magin = 15;
@interface GQCircleLoadView()<CAAnimationDelegate>
@property (nonatomic, strong) NSMutableArray *layerArr;
@end

@implementation GQCircleLoadView
- (instancetype)initWithFrame:(CGRect)frame{
 if (self = [super initWithFrame:frame]) {
  self.backgroundColor = [UIColor clearColor];
 }
 return self;
}
// 画圆
- (void)drawCircles{
 for (NSInteger i = 0; i < circleCount; ++i) {
  CGFloat x = (WINDOW_width - (cornerRadius*2) * circleCount - magin * (circleCount-1)) / 2.0 + i * (cornerRadius*2 + magin) + cornerRadius;
  CGRect rect = CGRectMake(-cornerRadius, -cornerRadius , 2*cornerRadius, 2*cornerRadius);
  UIBezierPath *beizPath=[UIBezierPath bezierPathWithRoundedRect:rect cornerRadius:cornerRadius];
  CAShapeLayer *layer=[CAShapeLayer layer];
  layer.path=beizPath.CGPath;
  layer.fillColor=[UIColor grayColor].CGColor;
  layer.position = CGPointMake(x, self.frame.size.height * 0.5);
  [self.layer addSublayer:layer];

  [self.layerArr addObject:layer];
 }

 [self drawAnimation:self.layerArr[0]];

 // 旋转(可打开试试效果)
// CABasicAnimation* rotationAnimation = [CABasicAnimation animationWithKeyPath:@"transform.rotation.y"];
// rotationAnimation.toValue = [NSNumber numberWithFloat: - M_PI * 2.0 ];
// rotationAnimation.duration = 1;
// rotationAnimation.cumulative = YES;
// rotationAnimation.repeatCount = MAXFLOAT;
// [self.layer addAnimation:rotationAnimation forKey:@"rotationAnimation"];
}

// 动画实现
- (void)drawAnimation:(CALayer*)layer {
 CABasicAnimation *scaleUp = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
 scaleUp.fromValue = @1;
 scaleUp.toValue = @1.5;
 scaleUp.duration = 0.25;
 scaleUp.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

 CABasicAnimation *scaleDown = [CABasicAnimation animationWithKeyPath:@"transform.scale"];
 scaleDown.beginTime = scaleUp.duration;
 scaleDown.fromValue = @1.5;
 scaleDown.toValue = @1;
 scaleDown.duration = 0.25;
 scaleDown.timingFunction = [CAMediaTimingFunction functionWithName:kCAMediaTimingFunctionEaseOut];

 CAAnimationGroup *group = [[CAAnimationGroup alloc] init];
 group.animations = @[scaleUp, scaleDown];
 group.repeatCount = 0;
 group.duration = scaleUp.duration + scaleDown.duration;
 group.delegate = self;
 [layer addAnimation:group forKey:@"groupAnimation"];

}
#pragma mark - CAAnimationDelegate
- (void)animationDidStart:(CAAnimation *)anim
{
 if ([anim isKindOfClass:CAAnimationGroup.class]) {
  CAAnimationGroup *animation = (CAAnimationGroup *)anim;

  [self.layerArr enumerateObjectsUsingBlock:^(CAShapeLayer *obj, NSUInteger idx, BOOL * _Nonnull stop) {

   CAAnimationGroup *a0 = (CAAnimationGroup *)[obj animationForKey:@"groupAnimation"];
   if (a0 && a0 == animation) {
    CAShapeLayer *nextlayer = self.layerArr[(idx+1)>=self.layerArr.count?0:(idx+1)];
    [self performSelector:@selector(drawAnimation:) withObject:nextlayer afterDelay:0.25];
    *stop = YES;
   }
  }];
 }
}
- (void)drawRect:(CGRect)rect{
 [super drawRect:rect];
 [self drawCircles];
}
- (NSMutableArray *)layerArr{
 if (_layerArr == nil) {
  _layerArr = [[NSMutableArray alloc] init];
 }
 return _layerArr;
}
@end

Demo就不上传了,总共四个文件代码已经全贴上了!

总结

以上就是这篇文章的全部内容了,有兴趣可以试试打开上面的旋转的动画代码,关闭旋转代码,进一步修改也可实现出QQ邮箱的下拉刷新效果,希望这篇文章的内容对大家的学习或者工作能带来一定的帮助,如果有疑问大家可以留言交流。

相关文章

  • iOS App设计模式开发中对迭代器模式的使用示例

    iOS App设计模式开发中对迭代器模式的使用示例

    这篇文章主要介绍了iOS App设计模式开发中对迭代器模式的使用示例,示例代码为传统的Objective-C,需要的朋友可以参考下
    2016-03-03
  • iOS应用内实现跳转到手机淘宝天猫的方法

    iOS应用内实现跳转到手机淘宝天猫的方法

    这篇文章主要给大家介绍了关于iOS应用内如何实现跳转到手机淘宝天猫的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有具有一定的参考学习价值,需要的朋友们下面来一起学习学习吧。
    2017-12-12
  • ios开发中的容错处理示例详解

    ios开发中的容错处理示例详解

    最近发现还是有很多朋友在问类似解析时容错问题怎么解决,所以下面这篇文章主要给大家介绍了关于ios开发中的容错处理的相关资料,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们一起来看看吧
    2018-05-05
  • iOS单例的创建与销毁示例

    iOS单例的创建与销毁示例

    本篇文章主要介绍了iOS单例的创建与销毁示例,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-02-02
  • 详解iOS App开发中session和coockie的用户数据存储处理

    详解iOS App开发中session和coockie的用户数据存储处理

    iOS在HTTP网络编程环境方面提供了NSURLSession、NSHTTPCookieStorage和NSHTTPCookie类来处理session和coockie的相关内容,接下来我们将来详解iOS App开发中session和coockie的用户数据存储处理:
    2016-06-06
  • iOS常用算法之两个有序数组合并(要求时间复杂度为0(n))

    iOS常用算法之两个有序数组合并(要求时间复杂度为0(n))

    这篇文章主要介绍了iOS常用算法之两个有序数组合并(要求时间复杂度为0(n)),实现思路是先将一个数组作为合并后的数组, 然后遍历第二个数组的每项元素,需要的朋友可以参考下
    2019-07-07
  • iOS常见算法以及应用知识点总结

    iOS常见算法以及应用知识点总结

    在本篇文章里小编给大家分享的是关于iOS常见算法以及应用知识点总结,有兴趣的朋友们学习下。
    2019-10-10
  • iOS开发之APP相关

    iOS开发之APP相关

    本文给大家介绍的是IOS开发系列文章的第一篇,给大家分享一些APP相关的知识点,非常的实用,有需要的小伙伴可以参考下
    2016-04-04
  • iOS中containsString和rangeOfString的区别小结

    iOS中containsString和rangeOfString的区别小结

    这篇文章主要给大家总结介绍了关于iOS中containsString和rangeOfString的一些区别,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧。
    2018-01-01
  • 详解使用ISO镜像搭建私有yum源

    详解使用ISO镜像搭建私有yum源

    这篇文章主要介绍了详解使用ISO镜像搭建私有yum源,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-06-06

最新评论