新壁纸镇楼
前言
其实没什么可前言的、有图谁哔哔是吧。
如果符合你的需求、再继续往下看原理
正文
项目里之前的写法是这样的
- (void)checkData {
[self hideHUD];
[self.tableView reloadData];
[self.tableView.mj_header endRefreshing];
[self.tableView.mj_footer endRefreshing];
if (self.dataArray.count == 0) {
[self showNoteView];
}else {
[self removeNoteview];
}
}
然后具体是每个页面创建一个NoteView。根据需要展示。
为什么这样写呢、我也不知道。反正一直按着公司旧代码copy着来了。
这样写功能实现上并没什么问题、实际使用也是。过程简单易懂。
不过、这样写。肯定是有问题的:
1.确实是为了过程而过程了。
2.每一个列表VC都要copy一份创建的代码啊真的是一模一样啊。满地都是啊。
3.也是最重要的。领导一直看着这个代码块很不顺眼~~去年说过让我解决一下但是我一直没弄...不过、去年的任务总不能拖到春节以后对吧?
哼(ˉ(∞)ˉ)唧 哼(ˉ(∞)ˉ)唧
解决实现
我们自然是希望以上需求与tableView绑定成为其固有功能。每次网络请求结束之后、自动检查数据源、而后处理。
网络请求我们从tableView中无法直接跟踪、但只要把相应操作注入到reloadData方法里就行了。
所以接下来。swizzle(别忘了头文件#import <objc/runtime.h>)
+ (void)load {
static dispatch_once_t onceToken;
dispatch_once(&onceToken, ^{
[[UITableView new] swizzleMethod:@selector(reloadData) withMethod:@selector(KTreloadData)];
});
}
- (void)swizzleMethod:(SEL)origSelector withMethod:(SEL)newSelector
{
Class class = [self class];
Method originalMethod = class_getInstanceMethod(class, origSelector);
Method swizzledMethod = class_getInstanceMethod(class, newSelector);
BOOL didAddMethod = class_addMethod(class,
origSelector,
method_getImplementation(swizzledMethod),
method_getTypeEncoding(swizzledMethod));
if (didAddMethod) {
class_replaceMethod(class,
newSelector,
method_getImplementation(originalMethod),
method_getTypeEncoding(originalMethod));
} else {
method_exchangeImplementations(originalMethod, swizzledMethod);
}
}
现在我们成功的修改了reloadData方法的指针指向了KTreloadData
在KTreloadData方法中对操作进行注入就行了
- (void)KTreloadData {
[self KTreloadData];
if (self.noteView) {
[self checkDataSource];
}
}
关于这个if、由于Catergory会直接全局加载。要有个属性判断当前的talbeView是否需要继续进行代码注入才行。
//工作代码~就这么几行
- (void)checkDataSource {
//需求是没有数据则不允许下拉刷新。如果不要阻隔下拉动作。则把self.noteView置于self上、或者将self.noteView的层级调至self之下即可
id <UITableViewDataSource> dataSource = self.dataSource;
NSInteger numberOfSections = [dataSource numberOfSectionsInTableView:self];
for (int i = 0; i < numberOfSections; i++) {
// 任意一行有内容、则移除noteView
if ( [dataSource tableView:self numberOfRowsInSection:i] != 0) {
[self.noteView removeFromSuperview];
return;
}
}
// [self addSubview:self.noteView];
[self.superview addSubview:self.noteView];
然后、用起来是这样的
[self.tableView addNoteViewWithpicName:@"bg_no_grab" noteText:@"我们的需求是btn刷新、硬要下拉刷新看类别里" refreshBtnImg:@"detail_btn_filladdress.png"];
就是最上面所展示的默认效果了(最后一个参数不填就不显示btn了)。
当然、也可以自定义。
UILabel * customNoteView = [[UILabel alloc]initWithFrame:CGRectMake(100, 100, 200, 100)];
customNoteView.numberOfLines = 0;
customNoteView.text = @"I am the Custom NoteView I am the Custom NoteView I am the Custom NoteView I am the Custom NoteView I am the Custom NoteView I am the Custom NoteView ";
self.tableView.noteView = customNoteView;
效果长这样
最后
最近在学习前端所以不太有时间造轮子什么的、不过demo还是有的。
https://github.com/kiritoSong/KTTableViewEmptyDemo
如果大家需求差不多、拿回去自己改改比集成各种tableView效果的三方库要舒服一些。反正不难、毕竟学到手了就是自己的嘛。
PS:Catergory是个好东西、可以帮我们提升很多权限解决很多问题。不过、并不是所有时候都适用、尤其是不要把建Catergory当成习惯~(嗯、不要问我怎么知道的)