造这个轮子的原因
几乎每个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
封装loading图view很常规,根据产品需求搭建UI即可,建议用自动布局。
3.对loading图的管理和控制:CQHUD
.h文件
#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]; }
对loading图的管理和控制其实就是对那个单例对象进行处理。
使用
//?展示loading [CQHUD?showLoading]; //?禁止用户交互 [CQHUD?enableUserInteraction:NO]; //?展示loading,说明信息:支付中 [CQHUD?showLoadingWithMessage:@"支付中"]; //?展示loading并且允许用户交互 [CQHUD?showLoadingWithEnableUserInteraction:YES]; //?展示loading提示“支付中”并且禁止用户交互 [CQHUD?showLoadingWithMessage:@"支付中"?enableUserInteraction:NO]; //?移除loading [CQHUD?dismiss];
demo
最后
暂时还没有研究SVProgressHUD和MBProgressHUD的源代码,等我练出6块腹肌就有时间研究了,希望有好心人可以打赏一元让我多买一个鸡蛋早日练出6块腹肌。
作者:无夜之星辰
链接:http://www.jianshu.com/p/7c1c353b9cd9
來源:简书
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。