原文
造這個輪子的原因
幾乎每個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
來源:簡書
著作權歸作者所有。商業轉載請聯系作者獲得授權,非商業轉載請注明出處。