iOS开发造轮子 | Loading图

原文

iOS开发造轮子 | Loading图

造这个轮子的原因

几乎每个app都有loading图,虽然有SVProgressHUD和MBProgressHUD这些非常优秀的三方,但我还是觉得要自己会封装才是王道,毕竟:

  1. 直接拿来的不一定满足需求,尤其是产品迭代较快、需求比较奇葩的时候

  2. 万一哪天这个三方没人维护了怎么办?还是用自己的踏实

效果演示

iOS开发造轮子 | Loading图

分析loading图

一般说来,loading图就是一个覆盖全屏的自定义view,并且你不可能同时看到两个loading图,所以loading图是单例。用得最多的场景是请求数据的时候展示,请求数据完成就移除。

根据我有限的经验,loading图往往需要满足这个需求:

可控的用户交互。

比如说,用户支付的时候,这个时候我们是不希望用户进行任何操作的。另一种情况,用户跳转到一个新页面,这个页面请求数据展示loading图,loading图挡住了返回按钮,从用户的角度来看,用户是希望可以随时点击返回按钮返回上一页的,而不是只能等着数据加载完成后才能进行操作。(类似于我demo演示的情况)

功能实现

1.文件说明

iOS开发造轮子 | Loading图

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?tartAnimating];
????????[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

來源:简书

著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

PS:如果您想和业内技术大牛交流的话,请加qq群(527933790)或者关注微信公众 号(AskHarries),谢谢!

转载请注明原文出处:Harries Blog™ » iOS开发造轮子 | Loading图

赞 (0)

分享到:更多 ()

评论 0

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址