结合MJRefresh与LYEmptyView,优雅地显示emp
2018-11-12 本文已影响0人
不成活不疯魔
EasyEmptyTableView
关键字:代码无侵入 优雅
结合MJRefresh与LYEmptyView,优雅地显示emptyView。
Display emptyView easily with MJRefresh and LYEmptyView.
LYEmptyView实现了在tableView刷新时自动切换emptyView的显示隐藏.
本文实现了在MJRefresh刷新后,自动显示/隐藏emptyView的需求.
同时,针对部分同学第一次进入页面时需要隐藏emptyView的需求也做了适配。

使用方法
1.首先集成MJRefresh,LYEmptyView,EasyEmptyTableView
2.引入相关文件
#import <MJRefresh/MJRefresh.h>
#import <LYEmptyView/LYEmptyViewHeader.h>
#import "EasyEmptyTableView.h"
3.初始化EmptyView相关:
注意请在tableView初始化之后调用
- (void)setUpEasyEmptyView{
/**
分以下情况:
一:
自动显示emptyView,直接引用本库,并初始化即可
解释:因为LYEmptyView默认配置就是自动显示/隐藏
二:
第一次不显示emptyView,之后自动显示/隐藏,设置ly_emptyView.autoShowEmptyView = NO,并初始化即可
解释:第一次刷新数据之后,在MJRefreshComponent+Switch.h中,依据haveBeenInBefore属性更新了autoShowEmptyView=yes,
之后就是ly_emptyView控制自动显示/隐藏
*/
[self.tableView setUpEmptyView];
//如果第一次需要隐藏,请加上以下三行代码
if (_showEmptyViewAtFirstIn == NO) {
self.tableView.ly_emptyView.autoShowEmptyView = NO;
}
//add header
__weak typeof(self) wlf = self;
//mj_header开始刷新时会调用beginRefreshing
//beginRefreshing通过方法交换,调用ly_startLoading
self.tableView.mj_header = [MJRefreshNormalHeader headerWithRefreshingBlock:^{
[wlf setUpData];
}];
self.tableView.ly_emptyView.tapContentViewBlock = ^{
[wlf headerRefresh];
};
}
实现原理
1.利用MJRefreshComponent的开始、结束刷新事件控制emptyView的显示
2.新建MJRefreshComponent分类,交换beginRefreshing与endRefreshing方法
//交换MJRefreshComponent的方法是因为,footer与header都是继承于此类
//所以不论是footer还是header,都会在结束刷新后正确的显示/隐藏emptyView
+ (void)load{
Method m1, m2;
m1 = class_getInstanceMethod(self, @selector(beginRefreshing));
m2 = class_getInstanceMethod(self, @selector(customBeginRefreshing));
method_exchangeImplementations(m1, m2);
m1 = class_getInstanceMethod(self, @selector(endRefreshing));
m2 = class_getInstanceMethod(self, @selector(customEndRefreshing));
method_exchangeImplementations(m1, m2);
}
- (void)customBeginRefreshing{
[self customBeginRefreshing];
//如果是第一次进入,执行ly_startLoading
if (self.scrollView.haveBeenInBefore==NO) {
[self.scrollView ly_startLoading];
//将view的haveBeenInBefore属性设置为YES
self.scrollView.haveBeenInBefore = YES;
} else { //如果不是第一次进入,打开emptyView的autoShowEmptyView
self.scrollView.ly_emptyView.autoShowEmptyView = YES;
}
}
- (void)customEndRefreshing{
[self customEndRefreshing];
[self.scrollView ly_endLoading];
}
3.在tableView的分类中添加属性,以满足第一次需要隐藏emptyView的产品需求,如无此需求,此步骤可略过不看
static NSString* const haveBeenInBeforeKey = @"haveBeenInBeforeKey";
@implementation UIView (FirstIn)
- (void)setHaveBeenInBefore:(BOOL)haveBeenInBefore{
objc_setAssociatedObject(self, &haveBeenInBeforeKey, @(haveBeenInBefore), OBJC_ASSOCIATION_ASSIGN);
}
- (BOOL)haveBeenInBefore{
return [objc_getAssociatedObject(self, &haveBeenInBeforeKey) boolValue];
}
4.为tableView添加emptyView
- (void)setUpEmptyView{
LYEmptyView *emptyV = [LYEmptyView emptyViewWithImage:[UIImage imageNamed:@"EasyEmptyTableView.bundle/empty_page"] titleStr:@"暂无数据,点击重试" detailStr:nil];
self.ly_emptyView = emptyV;
}
5.数据请求开始,注意,如果不是通过mj_header的beginRefreshing方法发起请求,
将不会调用ly_startLoading,导致emptyView不显示,如果有此种情况,请自行处理
//mj_header开始刷新时会调用beginRefreshing
//beginRefreshing通过方法交换,调用ly_startLoading
[self.tableView.mj_header beginRefreshing];
6.数据请求完成后调用reloadData,再调用mj_header endRefreshing
[self.tableView reloadData];
//注意要在reloadData之后调用endRefreshing
//endRefreshing通过方法交换,调用ly_endLoading
[self.tableView.mj_header endRefreshing];