原文

造這個輪子的原因
幾乎每個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
實用小demo
最後
暫時還沒有研究SVProgressHUD和MBProgressHUD的源代碼,等我練出6塊腹肌就有時間研究了,希望有好心人可以打賞一元讓我多買一個雞蛋早日練出6塊腹肌。
作者:無夜之星辰
鏈接:http://www.jianshu.com/p/7c1c353b9cd9
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。