iOS利用CALayer實(shí)現(xiàn)動(dòng)畫加載的效果
首先來(lái)看看效果圖

實(shí)現(xiàn)過(guò)程如下
控制器調(diào)用就一句代碼:
[self showLoadingInView:self.view];
方便控制器如此調(diào)用,就要為控制器添加一個(gè)分類
.h文件
#import <UIKit/UIKit.h> #import "GQCircleLoadView.h" @interface UIViewController (GQCircleLoad) //顯示動(dòng)畫 - (void)showLoadingInView:(UIView*)view; //隱藏動(dòng)畫 - (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
接下來(lái)就是GQCircleLoadView繼承UIView,里面通過(guò)drawRect畫出圓圈,并且動(dòng)畫的實(shí)現(xiàn)
#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]];
// 旋轉(zhuǎn)(可打開試試效果)
// 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"];
}
// 動(dòng)畫實(shí)現(xiàn)
- (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就不上傳了,總共四個(gè)文件代碼已經(jīng)全貼上了!
總結(jié)
以上就是這篇文章的全部?jī)?nèi)容了,有興趣可以試試打開上面的旋轉(zhuǎn)的動(dòng)畫代碼,關(guān)閉旋轉(zhuǎn)代碼,進(jìn)一步修改也可實(shí)現(xiàn)出QQ郵箱的下拉刷新效果,希望這篇文章的內(nèi)容對(duì)大家的學(xué)習(xí)或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流。
相關(guān)文章
iOS對(duì)象指針和基礎(chǔ)數(shù)據(jù)類型的強(qiáng)轉(zhuǎn)詳解
最近在做一些小功能,忽然發(fā)現(xiàn)有的基礎(chǔ)數(shù)據(jù)轉(zhuǎn)換居然都忘記了。于是想著要趕緊整理下記下來(lái)!本文就是記錄的一些內(nèi)容,主要介紹了iOS中對(duì)象指針和基礎(chǔ)數(shù)據(jù)類型的強(qiáng)轉(zhuǎn),有需要的朋友們可以參考借鑒,下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧。2016-11-11
Flutter使用push pop方法及路由進(jìn)行導(dǎo)航詳解
這篇文章主要為大家介紹了Flutter使用push pop方法及路由進(jìn)行導(dǎo)航詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
iOS開發(fā)之?dāng)?shù)字每隔3位用逗號(hào)分隔
以前在做電商app時(shí)經(jīng)常會(huì)針對(duì)稍大的金額展示出來(lái),需要每隔千位添加逗號(hào)便于用戶識(shí)別,下面通過(guò)本文給大家分享ios中數(shù)字每隔3位用逗號(hào)分隔的實(shí)例代碼,需要的朋友參考下吧2017-09-09
Swift實(shí)現(xiàn)iOS應(yīng)用中短信驗(yàn)證碼倒計(jì)時(shí)功能的實(shí)例分享
這篇文章主要介紹了Swift實(shí)現(xiàn)iOS應(yīng)用中短信驗(yàn)證碼倒計(jì)時(shí)功能的實(shí)例分享,開啟和關(guān)閉倒計(jì)時(shí)功能的步驟實(shí)現(xiàn)比較關(guān)鍵,需要的朋友可以參考下2016-04-04
IOS 開發(fā)中發(fā)送e-mail的幾種方法總結(jié)
這篇文章主要介紹了IOS 開發(fā)中發(fā)送e-mail的幾種方法總結(jié)的相關(guān)資料,需要的朋友可以參考下2017-03-03

