LYEmptyView 1.3.1

LYEmptyView 1.3.1

[email protected] 维护。



  • 作者:
  • 李阳

LYEmptyView

不需要遵循协议,不需要设置代理,也不需要实现代理方法,只需这一行代码就可以为一个 UITableView/UICollectionView 集成空白页面占位图。
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];

注意点

1.除了 UITableView/UICollectionView 之外,这些 View(包括 UIScrollView)没有 DataSource,在代码层面无法判断是否有数据,需要手动管理显示和隐藏,请参考示例 8

特点 描述
与项目完全解耦 在需要集成的界面中加入一行代码即可集成,与现有代码没有耦合度
0学习成本 无需关心视图的显示和隐藏时机,只需加入一行代码即可,框架监听系统刷新 UI 的方法,内部进行计算后自动进行显示和隐藏
调用简单 利用分类+runtime,调用非常简便
高度自定义 利用继承特性,可以进行二次封装,从而使自定义更简便
支持所有刷新方法 reload...、insert...、delete...等方法。当项目调用这些刷新方法时,该框架都会自动根据 DataSource 进行计算和判断是否显示 emptyView

目录

一、效果展示

二、集成方式

1.Cocoapods方式集成: pod 'LYEmptyView'
使用时导入头文件 #import <LYEmptyView/LYEmptyViewHeader.h>

2.手动下载集成: 将LYEmptyView文件夹,导入你的工程
使用时导入头文件:#import "LYEmptyViewHeader.h"

三、使用参考示例

1.一行代码集成空内容视图

//框架方法
self.tableView.ly_emptyView = [LYEmptyView emptyViewWithImageStr:@"noData"
                                                        titleStr:@"暂无数据,点击重新加载"
                                                       detailStr:@""];

PS:可对库进行二次封装,调用更简洁(二次封装方法在下面的示例5中会讲到)

//二次封装方法,调用简洁
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];

完全低耦合,在你的项目中加入这一行代码就可集成
不管项目中是reloadData方法刷UI还是insert、delete等方式刷UI,不需做其他任何操作,只需这一行代码就可实现以下效果

2.自由选择空内容元素

交互事件可选择SEL或block方式
self.tableView.ly_emptyView = [LYEmptyView emptyActionViewWithImageStr:@"noData"
                                                              titleStr:@"无数据"
                                                             detailStr:@"请稍后再试!"
                                                           btnTitleStr:@"重新加载"
                                                                target:target
                                                                action:action];
self.tableView.ly_emptyView = [LYEmptyView emptyActionViewWithImageStr:@"noData"
                                                              titleStr:@""
                                                             detailStr:@""
                                                           btnTitleStr:@""
                                                         btnClickBlock:^{}];
//    imageStr    : 占位图片
//    titleStr    : 标题
//    detailStr   : 详细描述
//    btnTitleStr : 按钮标题                                                         

框架提供四个元素,传入相应元素的字符串即可显示对应元素(按钮的显示前提是传入target,action或btnClickBlock) 可根据项目需求,自由进行组合,如下只展示了部分组合效果

3.自定义空内容元素

特殊情况下,如果空内容状态布局不满足需求时,可进行自定义
通过方法 + (instancetype)emptyViewWithCustomView:(UIView *)customView;
传入一个View即可创建一个自定义的emptyView

self.tableView.ly_emptyView = [LYEmptyView emptyViewWithCustomView:customView];

4.自定义元素的UI样式

在这里自定义UI样式需要编写很多代码,无需担心,示例5中会讲解二次封装的方法,封装后调用时只需一行代码即可 ^_^

  //初始化一个emptyView
  LYEmptyView *emptyView = [LYEmptyView emptyActionViewWithImageStr:@"noData"
                                                           titleStr:@"无数据"
                                                          detailStr:@"请稍后再试!"
                                                        btnTitleStr:@"重新加载"
                                                      btnClickBlock:^{}];
  //元素竖直方向的间距
  emptyView.subViewMargin = 20.f;
  //标题颜色
  emptyView.titleLabTextColor = MainColor(90, 180, 160);
  //描述字体
  emptyView.detailLabFont = [UIFont systemFontOfSize:17];
  //按钮背景色
  emptyView.actionBtnBackGroundColor = MainColor(90, 180, 160);

  //设置空内容占位图
  self.tableView.ly_emptyView = emptyView;

这里只列出了常用的属性,更多属性请查阅LYEmptyView.h文件

5.二次封装

在第4小节的示例代码中,修改emptyView的样式需要逐个属性单独修改,如果在项目中的每个界面都这样写会显得很麻烦,且不易维护
解决方案是对库进行二次封装,封装后对UI样式进行单独管理,方便维护

1)新建一个类继承自LYEmptyView,例如demo中的MyDIYEmpty
2)重写- (void)prepare 方法,并修改想要改变的元素的UI样式
- (void)prepare{
    [super prepare];
    
    self.titleLabFont = [UIFont systemFontOfSize:25];
    self.titleLabTextColor = MainColor(90, 180, 160);
    
    self.detailLabFont = [UIFont systemFontOfSize:17];
    self.detailLabTextColor = MainColor(180, 120, 90);
    self.detailLabMaxLines = 5;
    
    self.actionBtnBackGroundColor = MainColor(90, 180, 160);
    self.actionBtnTitleColor = [UIColor whiteColor];
}

通过以上两步操作,就可以实现对样式的单独管理
调用方法不变,只是调用的类变为了MYDiyEmpty

self.tableView.ly_emptyView = [MyDIYEmpty emptyActionViewWithImageStr:@"noData"
                                                             titleStr:@"无数据"
                                                            detailStr:@"请稍后再试!"
                                                          btnTitleStr:@"重新加载"
                                                        btnClickBlock:^{}];
3)进一步封装显示元素内容,例如无数据状态图、无网络状态图

在MyDIYEmpty.h中定义方法+(instancetype)diyNoDataEmpty;
在MyDIYEmpty.m中实现该方法

+ (instancetype)diyNoDataEmpty{
    return [MyDIYEmpty emptyViewWithImageStr:@"nodata"
                                    titleStr:@"暂无数据"
                                   detailStr:@"请检查您的网络连接是否正确!"];
}

经过3步封装,自定义了UI样式,使管理更方便,调用更简洁
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];

6.延迟显示emptyView

如图例1所示,框架会根据DataSource的内容自动计算是否显示emptyView。在发起网络请求的空页面中,DataSource必定为空,会自动显示emptyView。但是有些产品需求可能不希望这样,希望在发起请求时暂时隐藏emptyView。此框架提供了两种方法来实现这个需求,这两种方法都是对scrollView的分类,调用非常方便

 /**
   一般用于开始请求网络时调用,ly_startLoading调用时会暂时隐藏emptyView
   当调用ly_endLoading方法时,ly_endLoading方法内部会根据当前的tableView/collectionView的
   DataSource来自动判断是否显示emptyView
 */
- (void)ly_startLoading;

 /**
   在想要刷新emptyView状态时调用
   注意:ly_endLoading 的调用时机,有刷新UI的地方一定要等到刷新UI的方法之后调用,
   因为只有刷新了UI,view的DataSource才会更新,故调用此方法才能正确判断是否有内容。
 */
- (void)ly_endLoading;

*注意事项:使用这两种方法时,请先将emptyView的autoShowEmptyView属性设置为NO,关闭自动显隐

以下是调用示例(具体细节可参考demo中的demo2)

//1.先设置样式
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];
//2.关闭自动显隐(此步可封装进自定义类中,相关调用就可省去这步)
self.tableView.ly_emptyView.autoShowEmptyView = NO;
//3.网络请求时调用
[self.tableView ly_startLoading];
//4.刷新UI时调用(保证在刷新UI后调用)
[self.tableView ly_endLoading];

7.特殊需求,手动控制emptyView的显示隐藏

在某些特殊界面下,一些tableView/collectionView有固定的一些死数据,其余的数据根据网络加载,这时可能无法满足上述需求。
本框架提供另外的两个方法来解决这个问题。

/**
 手动调用显示emptyView
 */
- (void)ly_showEmptyView;

/**
 手动调用隐藏emptyView
 */
- (void)ly_hideEmptyView;

*注意事项:使用这两种方法时,请先将emptyView的autoShowEmptyView属性设置为NO,关闭自动显隐

以下为调用示例(具体细节可参考demo中的demo4)

//1.先设置样式
self.tableView.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];
//2.关闭自动显隐(此步可封装进自定义类中,相关调用就可省去这步)
self.tableView.ly_emptyView.autoShowEmptyView = NO;
//3.显示emptyView
[self.tableView ly_showEmptyView];
//4.隐藏emptyView
[self.tableView ly_hideEmptyView];

8.普通view调用示例

由于普通view(包括scrollView)没有DataSource,在代码层面无法判断view上是否有数据,因此想要实现占位图,还需通过两个方法来手动控制emptyView的显示和隐藏。以下为调用示例

//1.先设置样式
self.view.ly_emptyView = [MyDIYEmpty diyNoDataEmpty];
//2.显示emptyView
[self.view ly_showEmptyView];
//3.隐藏emptyView
[self.view ly_hideEmptyView];

9.占位图完全覆盖父视图

每个项目的需求不同,有的占位图内容多大,占位图就多大,这种情况是默认的,无需设置属性。而有的占位图想要与父视图一样大,以达到覆盖父视图的目的,这种情况下将LYEmptyView的emptyViewIsCompleteCoverSuperView属性值设置为YES即可。

DemoEmptyView *emptyView = [DemoEmptyView diyEmptyView];
emptyView.emptyViewIsCompleteCoverSuperView = YES;//完全覆盖父视图,背景色默认为浅白色,可自行设置
//emptyView.backgroundColor = [UIColor redColor];//自己设置背景色为红色,此设置也可封装到公共的地方(DemoEmptyView),就不用每次都单独设置了
self.tableView.ly_emptyView = emptyView;

更新记录

2019-08-16 (pod V1.3.0)

  • 1.为detailLab添加行间距属性
  • 2.每个子控件可以单独设置间距
  • 3.actionBtn添加渐变背景颜色属性
  • 4.更改添加emptyView时其显隐的逻辑

2019-07-04 (pod V1.2.5)

  • 1.新增属性:按钮宽度actionBtnWidth
  • 2.修改属性默认值:按钮圆角actionBtnCornerRadius默认改为0

2019-06-18 (pod V1.2.4)

  • 1.将点击重试事件添加到emptyView上(当设置empty完全覆盖父视图时,可以实现在屏幕上点击重试的效果)
  • 在2.swift项目中,解决imageNamed:方法字符串为nil时的崩溃问题

2018-12-04 (pod V1.2.3)

  • 1.修复bug:当子控件的文字设置为空值并再次设置为非空值时,子控件无法正常显示
  • 2.新增属性:ignoreContentInset,是否忽略scrollView的contentInset

2018-09-11 (pod V1.2.2)

  • 新增构造方法,具体请查看LYEmptyBaseView.h

2018-08-22 (pod V1.2.1)

  • 大神的建议,不要手动调用layoutSubviews。优化baseView里setter方法调用的重绘机制,使用setNeedsLayout更加优雅

2018-07-31 (pod V1.2.0)

  • 新增属性:emptyViewIsCompleteCoverSuperView, 占位图是否完全覆盖父视图

2018-05-11 (pod V1.1.0)

  • 新增普通View可设置占位图,实现所有的View都能集成占位图

2018-03-26 (pod V1.0.3)

  • 添加reloadSections、reloadRows、reloadItems等方法的事件监听
  • emptyBaseView setter方法bug修复

2018-02-09 (pod V1.0.2)

  • 仅在导入本框架时,解决导致UIScrollView上内容不显示的bug

技术交流

本人QQ:944801216
技术交流群:818290484
大家有任何问题或建议,可以联系我,我一定尽力为大家解决问题,也可以加入群组和大家一起交流。