iOS开发造轮子|Loading图
造这个轮子的原因
几乎每个app都有loading图,虽然有SVProgressHUD和MBProgressHUD这些非常优秀的三方,但我还是觉得要自己会封装才是王道,毕竟:
直接拿来的不一定满足需求,尤其是产品迭代较快、需求比较奇葩的时候
万一哪天这个三方没人维护了怎么办?还是用自己的踏实
效果演示
分析loading图
一般说来,loading图就是一个覆盖全屏的自定义view,并且你不可能同时看到两个loading图,所以loading图是单例。用得最多的场景是请求数据的时候展示,请求数据完成就移除。
根据我有限的经验,loading图往往需要满足这个需求:
可控的用户交互。
比如说,用户支付的时候,这个时候我们是不希望用户进行任何操作的。另一种情况,用户跳转到一个新页面,这个页面请求数据展示loading图,loading图挡住了返回按钮,从用户的角度来看,用户是希望可以随时点击返回按钮返回上一页的,而不是只能等着数据加载完成后才能进行操作。(类似于我demo演示的情况)
功能实现
1.文件说明
CQLoadingView是对loading图的封装;
CQHUD是对loading图的管理和控制。
2.封装loading图view:CQLoadingView
.h文件
#import?@interface?CQLoadingView?:?UIView
/**?loading信息?*/
@property?(nonatomic,?copy)?NSString?*loadingInfo;
/**?loading图单例?*/
+?(instancetype)sharedInstance;
@end
.m文件
#import?"CQLoadingView.h"
#import?@implementation?CQLoadingView{
????
/**?loading信息label?*/
????UILabel?*_loadingInfoLabel;
}
static?CQLoadingView?*loadingView;
#pragma?mark?-?loading图单例
/**?loading图单例?*/
+?(instancetype)sharedInstance?{
????
if
?(loadingView?==?nil)?{
????????loadingView?=?[[CQLoadingView?alloc]?init];
????}
????
return
?loadingView;
}
#pragma?mark?-?构造方法
-?(instancetype)initWithFrame:(CGRect)frame?{
????
if
?(self?=?[
super
?initWithFrame:frame])?{
????????self.backgroundColor?=?[UIColor?colorWithWhite:0.2?alpha:0.2];
????????
//-------?loading?imageView?-------//
????????UIImageView?*loadingImageView?=?[[UIImageView?alloc]?initWithFrame:CGRectMake(10,?10,?45,?45)];
????????[self?addSubview:loadingImageView];
????????loadingImageView.image?=?[UIImage?imageNamed:@
"loading_00000"
];
????????NSMutableArray?*imageArray?=?[NSMutableArray?array];
????????
for
?(int?i?=?0;?i?<!--?15;?i?++)?{
????????????NSString?*imageName?=?[NSString?stringWithFormat:@
"loading_d"
,i];
????????????[imageArray?addObject:[UIImage?imageNamed:imageName]];
????????}
????????loadingImageView.animationImages?=?imageArray;
????????loadingImageView.animationDuration?=?0.5;
????????loadingImageView.animationRepeatCount?=?0;
????????[loadingImageView?startAnimating];
????????[loadingImageView?mas_makeConstraints:^(MASConstraintMaker?*make)?{
????????????make.center.mas_equalTo(self);
????????????make.size.mas_equalTo(CGSizeMake(45,?45));
????????}];
????????1
????????
//-------?说明文本?-------//
????????_loadingInfoLabel?=?[[UILabel?alloc]?init];
????????[self?addSubview:_loadingInfoLabel];
????????_loadingInfoLabel.textAlignment?=?NSTextAlignmentCenter;
????????_loadingInfoLabel.font?=?[UIFont?systemFontOfSize:14];
????????_loadingInfoLabel.textColor?=?[UIColor?redColor];
????????[_loadingInfoLabel?mas_makeConstraints:^(MASConstraintMaker?*make)?{
????????????make.centerX.mas_equalTo(loadingImageView);
????????????make.top.mas_equalTo(loadingImageView.mas_bottom).mas_offset(20);
????????????make.height.mas_equalTo(18);
????????}];
????}
????
return
?self;
}
#pragma?mark?-?赋值loading说明信息
/**?赋值loading说明信息?*/
-?(void)setLoadingInfo:(NSString?*)loadingInfo{
????_loadingInfo?=?loadingInfo;
????_loadingInfoLabel.text?=?_loadingInfo;
}
@end</pre--><p>封装loading图view很常规,根据产品需求搭建UI即可,建议用自动布局。</p><p><span style=
"font-size: 18px;"
><strong>3.对loading图的管理和控制:CQHUD</strong></span></p><p><strong>.h文件</strong></p><pre class=
"brush:js;toolbar:false"
>
#pragma?mark?-?展示loading图
/**?展示loading图?*/
+?(void)showLoading;
#pragma?mark?-?展示带说明信息的loading图
/**
?带说明信息loading图
?
?@param?message?说明信息
?*/
+?(void)showLoadingWithMessage:(NSString?*)message;
#pragma?mark?-?移除loading图
/**?移除loading图?*/
+?(void)dismiss;
#pragma?mark?-?loading期间,允许或禁止用户交互
/**
?loading期间,允许或禁止用户交互
?1
?@param?isEnable?YES:允许?NO:禁止
?*/
+?(void)enableUserInteraction:(BOOL)isEnable;
#pragma?mark?-?展示可控制用户交互的loading图
/**
?展示可控制用户交互的loading图
?
?@param?isEnable?是否允许用户交互
?*/
+?(void)showLoadingWithEnableUserInteraction:(BOOL)isEnable;
#pragma?mark?-?展示可控制用户交互并且带说明信息的loading图
/**
?展示可控制用户交互并且带说明信息的loading图
?
?@param?message?说明信息
?@param?isEnable?是否允许用户交互
?*/
+?(void)showLoadingWithMessage:(NSString?*)message?enableUserInteraction:(BOOL)isEnable;
.m文件
#pragma?mark?-?展示loading图
/**?展示loading图?*/
+?(void)showLoading?{
????[CQHUD?showLoadingWithMessage:nil];
}
#pragma?mark?-?展示带说明信息的loading图
/**
?带说明信息loading图
?@param?message?说明信息
?*/
+?(void)showLoadingWithMessage:(NSString?*)message?{
????UIWindow?*?window?=?[[[UIApplication?sharedApplication]?delegate]?window];
????[window?addSubview:[CQLoadingView?sharedInstance]];
????[CQLoadingView?sharedInstance].loadingInfo?=?message;
????[[CQLoadingView?sharedInstance]?mas_makeConstraints:^(MASConstraintMaker?*make)?{
????????make.edges.mas_equalTo(UIEdgeInsetsMake(0,?0,?0,?0));
????}];
}
#pragma?mark?-?移除loading图
/**?移除loading图?*/
+?(void)dismiss?{
????[[CQLoadingView?sharedInstance]?removeFromSuperview];
}
#pragma?mark?-?loading期间,允许或禁止用户交互
/**
?loading期间,允许或禁止用户交互
?@param?isEnable?YES:允许?NO:禁止
?*/
+?(void)enableUserInteraction:(BOOL)isEnable?{
????[CQLoadingView?sharedInstance].userInteractionEnabled?=?!isEnable;
}
#pragma?mark?-?展示可控制用户交互的loading图
/**
?展示可控制用户交互的loading图
?@param?isEnable?是否允许用户交互
?*/
+?(void)showLoadingWithEnableUserInteraction:(BOOL)isEnable?{
????[CQHUD?showLoading];
????[CQHUD?enableUserInteraction:isEnable];
}
#pragma?mark?-?展示可控制用户交互并且带说明信息的loading图
/**
?展示可控制用户交互并且带说明信息的loading图
?@param?message?说明信息
?@param?isEnable?是否允许用户交互
?*/
+?(void)showLoadingWithMessage:(NSString?*)message?enableUserInteraction:(BOOL)isEnable?{
????[CQHUD?showLoadingWithMessage:message];
????[CQHUD?enableUserInteraction:isEnable];
}</pre><p>对loading图的管理和控制其实就是对那个单例对象进行处理。</p><p><span style=
"font-size: 20px;"
><strong>使用</strong></span></p><pre class=
"brush:js;toolbar:false"
>
//?展示loading
[CQHUD?showLoading];
//?禁止用户交互
[CQHUD?enableUserInteraction:NO];
//?展示loading,说明信息:支付中
[CQHUD?showLoadingWithMessage:@
"支付中"
];
//?展示loading并且允许用户交互
[CQHUD?showLoadingWithEnableUserInteraction:YES];
//?展示loading提示“支付中”并且禁止用户交互
[CQHUD?showLoadingWithMessage:@
"支付中"
?enableUserInteraction:NO];
//?移除loading
[CQHUD?dismiss];</pre><p><span style=
"font-size: 20px;"
><strong>demo</strong></span></p><p><a href=
"https://github.com/CaiWanFeng/AlertToastHUD"
target=
"_self"
>实用
