零行代码为App添加异常加载占位图
前文提要
近期准备重构项目,需要重写一些通用模块,正巧需要设置App异常加载占位图的问题,心血来潮设想是否可以零行代码解决此问题,特在此分享实现思路。
思路分享
对于App占位图,通常需要考虑的控件有tableView、collectionView和webView,异常加载情况区分为无数据和网络异常等。
既然要实现零代码形式,因此就不能继承原始类重写或添加方法等方式,而是通过对对应控件添加类别(分类)来实现。
简单来说,以tableView为例实现思路为每当tableView调用reloadData进行刷新时,检测此时tableView行数,若行数不为零,正常显示数据。若行数为零,说明无数据显示占位图。
添加占位图的方式有很多种,例如借助tableView的backgroundView或直接以addSubView的方式添加,这里采用的为addSubView方式,尽量避免原生属性的占用。
对于检测tableView数据是否为空,借助tableView的代理dataSource即可。核心代码如下,依次获取tableView所具有的组数与行数,通过isEmpty这个flag标示最后确定是否添加占位图。
- (void)checkEmpty {
BOOL isEmpty = YES;//flag标示
id <UITableViewDataSource> dataSource = self.dataSource;
NSInteger sections = 1;//默认一组
if ([dataSource respondsToSelector:@selector(numberOfSectionsInTableView:)]) {
sections = [dataSource numberOfSectionsInTableView:self] - 1;//获取当前TableView组数
}
for (NSInteger i = 0; i <= sections; i++) {
NSInteger rows = [dataSource tableView:self numberOfRowsInSection:i];//获取当前TableView各组行数
if (rows) {
isEmpty = NO;//若行数存在,不为空
}
}
if (isEmpty) {//若为空,加载占位图
if (!self.placeholderView) {//若未自定义,展示默认占位图
[self makeDefaultPlaceholderView];
}
self.placeholderView.hidden = NO;
[self addSubview:self.placeholderView];
} else {//不为空,隐藏占位图
self.placeholderView.hidden = YES;
}
}
相应的对于CollectionView亦可通过numberOfSectionsInCollectionView:
和collectionView:numberOfItemsInSection
获取其组数和行数,这里就不一一赘述。
需要注意的为webView占位图是否显示的判断,一种情况为webView调用其webView: didFailLoadWithError:
方法,第二种为webView完成加载显示为空的情况。但存在的一个问题是,webView没有必选的协议方法,或可能根本没有设置代理。因此无法很好的判断webView是否响应其协议方法。因此该demo暂时没有添加webView的占位图,如果有好的想法可以评论指出。
接下来说最重要的一步,如何实现零行代码添加占位图呢?
其实实现思路非常简单,如果可以让tableView在执行reloadData时自动检测其行数就可以了。也就是我们需要在reloadData原有方法的基础上添加checkEmpty此方法。
这里又能体现到Runtime Method Swizzling的作用了,我们可以通过Method Swizzling替换reloadData方法,给予它新的实现。核心代码如下:
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
//方法交换,将reloadData实现交换为sure_reloadData
[self methodSwizzlingWithOriginalSelector:@selector(reloadData) bySwizzledSelector:@selector(sure_reloadData)];
});
}
- (void)sure_reloadData {
[self checkEmpty];
[self sure_reloadData];
}
这样就可以实现reloadData的同时检测行数从而判断是否显示占位图的功能。
这里采用了上篇文章《Runtime Method Swizzling开发实例汇总》的代码用例类NSObject+Swizzling.h
,因此该篇文章也算上篇文章的延续,为Runtime Method Swizzling的另一种用例。感兴趣的朋友可以前往阅读更多的实用用例。
为实现零代码的效果,代码中已添加了placeholder视图的默认样式,如图所示:

若要实现效果图中点击图标重新刷新效果,需要让tableView调用reloadBlock,因为数据的刷新大多是不同的,所以具体刷新执行代码还是需要自己手动设置的。若不需要,则无需添加此操作。
[_tableView setReloadBlock:^{
//刷新操作
}];
如果需要自定制占位视图样式也非常简单,因占位图样式比较统一,所以可直接修改SurePlaceholderView
占位图类以达到自己想要的效果,再而在UITableView+Sure_Placeholder.h
、UICollectionView+Sure_Placeholder.h
、UIWebView+Sure_Placeholder.h
类别中均外漏了placeholderView属性,将其赋值为新的视图亦可。
以tableView为例,可以通过如下方式进行修改
_tableView.placeholderView =[[CustomPlaceholderView alloc]initWithFrame:_tableView.bounds];
同样的对于无数据与无网络的效果切换,也可以通过网络是否可用的标示来进行展示不同的占位图。例如
if (is_Net_Available) {
_tableView.placeholderView = [[CustomPlaceholderView alloc]initWithFrame:_tableView.bounds];
} else {
_tableView.placeholderView = [[NetNoAvailableView alloc]initWithFrame:_tableView.bounds];
}
为方便大家阅读和修改,demo已上传github。
下载链接如下: 前文提要 近期准备重构项目,需要重写一些通用模块,正巧需要设置App异常加载占位图的问题,心血来潮设想是否可以零行代码解决此问题,特在此分享实现思路. 思路分享 对于App占位图,通常需要考虑的控件有 ... 今天有几个好友问了这个叫加载占位图的实现方法,我还在此问题下做了个回答.由于国内对这个的名词是各有各的叫法,所以这里直接用加载占位图来解释.相信很多人都看到过图中这样的加载方式: 这个图是一个国内知名 ... 关注仓库,及时获得更新:iOS-Source-Code-Analyze https://github.com/draveness/iOS-Source-Code-Analyze Follow: Dra ... 学习asp.net mvc 时在更新实体进行SaveChanges()的时候出现了异常,异常如下: “/”应用程序中的服务器错误. 存储区更新.插入或删除语句影响到了意外的行数(0).实体在加载后可能 ... 今天我准备拿大众点评.美团.猫眼电影三款App的实例来分享一下APICloud下拉加载这个模块的效果. 美团App下拉加载效果 以美团中的下拉酷似动画的萌萌着小人儿效果作为参考,来实现的一个加载模 ... 当一个Vue的项目体积变得十分庞大的时候,使用Webpack的代码分离功能将Vue Components,routes或Vuex的代码进行分离并按需加载,会极大的提高App的首屏加载速度. 在Vue的 ... 当一个Vue的项目体积变得十分庞大的时候,使用Webpack的代码分离功能将Vue Components,routes或Vuex的代码进行分离并按需加载,会极大的提高App的首屏加载速度. 在Vue的 ... 在用asp.net MVC3 的MusicStore时候 Edit某个数据项时提示下面的错误: 存储区更新.插入或删除语句影响到了意外的行数(0).实体在加载后可能被修改或删除.刷新 ObjectSt ... 我们看到的APP,往往有着华丽的启动界面,然后就是漫长的数据加载等待,甚至在无网络的时候,整个处于不可用状态.那么我们怎么处理好界面交互中的加载设计,保证体验无缝衔接,保证用户没有漫长的等待感,而可以 ... 首先 下载 Android-PullToRefresh-master 下载地址 https://github.com/chrisbanes/Android-PullToRefresh 下载之后将其解 ... Unix/Linux版本众多,我们推荐Unix/Linux初学者选用几款典型的Unix/Linux操作系统进行学习. 1.广义的Debian是指一个致力于创建自由操作系统的合作组织及其作品,由于Deb ... C标准库qsort()函数的用法(快排) 使用快速排序例程进行排序 头文件:stdlib.h 用 法: void qsort(void *base, int nelem, int width, i ... iOS开发基本须要 1 准备好对应的硬件和软件配置------基于Intel处理器的Mac操作系统 2 具有C++,Java或其它面向对象编程语言的开发经验 3 最新的iphone SDK的下 ... 大家做开发最大的问题是什么?英语的问题应该困扰很多的同学的地方,我们提倡科学学习开发中的常用词汇.我们不要求大家有特别好的听.说.写,只要能够记住,能够认识这些常用词汇你以后的开发也将游刃有余.我们的 ... 一.分析 一般来说,我们经常使用的枚举项只有一个属性,即排序号,其默认值是从0.1.2... ....但是除了排序号外,枚举还有一个(或多个)属性. 二.场景 比如,可以通过枚举构造函数声明业务值,定 ... 本项目实现了用OpenGL绘制一个简单场景,包括正方体.球体和网格,实现了物体的旋转.缩放.平移和灯光效果.附有项目完整代码.有具体凝视.适合刚開始学习的人熟悉opengl使用. 开发情况 开发环境V ... 转载:http://www.uml.org.cn/success/201410205.asp 从去年到现在,从.NET转向Java开发(只是因为项目原因,绝对与平台好坏没有关系)差不多有一年的时间了. ... 全局函数与内置对象的属性或方法不是一个概念. 全局函数它不属于任何一个内置对象. JS中有14个全局函数 函数 描述 decodeURI() 解码某个编码的 URI. decodeURICompone ... 一.Fibonacci数列 问题描述 Fibonacci数列的递推公式为:Fn=Fn-1+Fn-2,其中F1=F2=1. 当n比较大时,Fn也非常大,现在我们想知道,Fn除以10007的余数是多少. ...
零行代码为App添加无数据占位图
零行代码为App添加异常加载占位图的更多相关文章
随机推荐