项目介绍:
JHLoadingForHJ 一个简单的加载动画
在上一篇中,笔者简要介绍了CAReplicatorLayer,在本篇中,将介绍具体的实用价值。实用CAReplicatorLayer作为核心技术实现加载动画。
首先,创建一个UIView的子类@interface JHHJView : UIView
然后该子类暴露出一些类方法:[Objective-C] 查看源文件 复制代码
/* 显示加载动画 并添加到父视图上 */ + (void)showLoadingOnView:(UIView *)superView Type:(JHHJViewType)type; /* 显示动画 并添加在主窗口上 */ + (void)showLoadingOnTheKeyWindowWithType:(JHHJViewType)type; /* 停止动画 */ + (void)hideLoading; /* 设置动画背景色(全屏背景色) */ + (void)backgroudColor:(UIColor *)color; /* 设置中心视图的动画背景颜色 默认透明色 */ + (void)centerBGViewBackgroudColor:(UIColor *)color;
并且声明了一个枚举类型:该枚举类型代表着加载动画类型。[Objective-C] 查看源文件 复制代码
typedef NS_ENUM(NSInteger,JHHJViewType){ /** * 线性动画 */ JHHJViewTypeSingleLine = 0, /** * 方形点动画 */ JHHJViewTypeSquare = 1, /** * 三角形运动动画 */ JHHJViewTypeTriangleTranslate = 2, /** * 原型视图裁剪动画 */ JHHJViewTypeClip };
在.m文件中,该类拥有的成员变量如下:[Objective-C] 查看源文件 复制代码
@interface JHHJView () //中心背景视图 @property (nonatomic,strong)JHHJCenterBGView *centerBGView; //计时器 @property (nonatomic,strong)NSTimer * clipTimer; //层数组 @property (nonatomic,strong)NSMutableArray * clipLayerArr; //计时器计量数 @property (nonatomic,assign) long long currentTimerIndex; //背景层 @property (nonatomic,strong) CAShapeLayer *bgLayer; @end
然后,设置以单例的方式创建该类的对象:[Objective-C] 查看源文件 复制代码
/** * 对象单例化 * * @return 单例对象 */ + (JHHJView *)shareInstanceJHHJView{ static JHHJView * instance = nil; if (!instance) { instance = [[JHHJView alloc] initWithFrame:[UIScreen mainScreen].bounds]; instance.centerBGView = [[JHHJCenterBGView alloc] initWithFrame:CGRectMake(0, 0, 100, 100)]; instance.centerBGView.center = CGPointMake(K_IOS_WIDTH / 2, K_IOS_HEIGHT/2); [instance addSubview:instance.centerBGView]; } return instance; }
最重要的一点,动画的实现如下:[Objective-C] 查看源文件 复制代码
/** * 展示动画视图 并添加到依赖视图上 * * @param superView 依赖的父视图 * @param type 动画样式 */ + (void)showLoadingOnView:(UIView *)superView Type:(JHHJViewType)type{ /* 在显示前 先从父视图移除当前动画视图 */ JHHJView *instance = [[self class] shareInstanceJHHJView]; [[self class] hideLoading]; /* 显示前 先将动画图层从中心视图上移除 */ for (CALayer *layer in instance.centerBGView.layer.sublayers) { [layer removeFromSuperlayer]; } /* 按照type初始化动画 */ switch (type) { case JHHJViewTypeSingleLine: { CALayer *layer = [instance lineAnimation]; layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2 - 25, CGRectGetHeight(instance.centerBGView.frame)/2); [instance.centerBGView.layer addSublayer:layer]; }break; case JHHJViewTypeSquare: { CALayer *layer = [[self class] qurareAnimation]; layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2, CGRectGetHeight(instance.centerBGView.frame)/2); [instance.centerBGView.layer addSublayer:layer]; }break; case JHHJViewTypeTriangleTranslate: { CALayer *layer = [[self class] triangleAnimation]; layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2 - 18, CGRectGetHeight(instance.centerBGView.frame)/2 - 15); [instance.centerBGView.layer addSublayer:layer]; }break; case JHHJViewTypeClip: { CALayer *layer = [[self class] clipAnimation]; layer.position = CGPointMake(CGRectGetWidth(instance.centerBGView.frame)/2 , CGRectGetHeight(instance.centerBGView.frame)/2 - 15); [instance.centerBGView.layer addSublayer:layer]; }break; default: break; } [superView addSubview:instance]; }
具体的流程即是以上,下面来具体实现其中一个动画,以三角形旋转动画为例:[Objective-C] 查看源文件 复制代码
/** * 三角形运动动画 * * @return 动画实例对象 */ + (CALayer *)triangleAnimation{ /* 基本间距确定及模板层的创建 */ CGFloat radius = 50/4.0; CGFloat transX = 50 - radius; CAShapeLayer *shape = [CAShapeLayer layer]; shape.frame = CGRectMake(0, 0, radius, radius); shape.path = [UIBezierPath bezierPathWithOvalInRect:CGRectMake(0, 0, radius, radius)].CGPath; shape.strokeColor = [UIColor redColor].CGColor; shape.fillColor = [UIColor redColor].CGColor; shape.lineWidth = 1; [shape addAnimation:[JHHJAnimation rotateAnimation] forKey:@"rotateAnimation"]; /* 创建克隆层 */ CAReplicatorLayer *replicatorLayer = [CAReplicatorLayer layer]; replicatorLayer.frame = CGRectMake(0, 0, radius, radius); replicatorLayer.instanceDelay = 0.0; replicatorLayer.instanceCount = 3; CATransform3D trans3D = CATransform3DIdentity; trans3D = CATransform3DTranslate(trans3D, transX, 0, 0); trans3D = CATransform3DRotate(trans3D, 120.0*M_PI/180.0, 0.0, 0.0, 1.0); replicatorLayer.instanceTransform = trans3D; [replicatorLayer addSublayer:shape]; return replicatorLayer; } JHHJAnimation这个类是为了分离代码,而创建的动画创建类,里面使用类方法创建各种核心动画,如: /** * 缩小动画 * */ + (CABasicAnimation *)animationForScaleSmall{ CABasicAnimation *basic = [CABasicAnimation animationWithKeyPath:@"transform"]; basic.fromValue = [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DIdentity, 1, 1, 0)]; basic.toValue = [NSValue valueWithCATransform3D:CATransform3DScale(CATransform3DIdentity, 0.2, 0.2, 0)]; basic.duration = 1.05; basic.repeatCount = HUGE; return basic; }
好了,基本的流程就是这样了,来个效果图:
这里只讲了样式3动画的实现步骤,如果需要理解其他动画样式的实现
DEMO 直接下载: