DZNEmptyDataSet是一款優(yōu)秀的處理數(shù)據(jù)集合為空的輕量型框架
基于 UITableView/UICollectionView 的category類(lèi),默認(rèn)情況下,如果我們的的表視圖是空的,屏幕上什么也不會(huì)顯示,它給用戶(hù)的體驗(yàn)不是很好。該庫(kù)可以很靈活地幫我們很好地處理集合視圖,然后合理美觀地顯示出用戶(hù)信息。
1,用法
使用的方法還是很簡(jiǎn)單, 下載官方的demo一看懂了,快捷方便,設(shè)置相應(yīng)代理即可
self.tableView.emptyDataSetSource = self;
self.tableView.emptyDataSetDelegate = self;
然后再根據(jù)具體的需要自定義自己App的顯示特點(diǎn),DZNEmptyDataSet為我們提供了豐富多種的設(shè)置方法,其中常用的方法有3個(gè)
/**
數(shù)據(jù)為空時(shí),顯示的提示標(biāo)語(yǔ)
*/
- (nullable NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView;
/**
數(shù)據(jù)為空時(shí),顯示的提示顯示內(nèi)容
*/
- (nullable NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView;
/**
數(shù)據(jù)為空時(shí),顯示的提示顯示圖像
*/
- (nullable UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView;
2,實(shí)現(xiàn)原理
關(guān)鍵的意思就運(yùn)用了runtime特性,替換掉UITableView 或者 UICollectionView 的reloadData 函數(shù)
// Swizzle by injecting additional implementation
Method method = class_getInstanceMethod(baseClass, selector);
IMP dzn_newImplementation = method_setImplementation(method, (IMP)dzn_original_implementation);
攔截該方法之后在適當(dāng)?shù)臅r(shí)機(jī)計(jì)算datasource的數(shù)量,如果總數(shù)量為空就像是相應(yīng)的視圖,否則還是按照原本的處理邏輯
- (NSInteger)dzn_itemsCount
{
NSInteger items = 0;
// UIScollView doesn't respond to 'dataSource' so let's exit
if (![self respondsToSelector:@selector(dataSource)]) {
return items;
}
// UITableView support
if ([self isKindOfClass:[UITableView class]]) {
UITableView *tableView = (UITableView *)self;
id <UITableViewDataSource> dataSource = tableView.dataSource;
NSInteger sections = 1;
if (dataSource && [dataSource respondsToSelector:@selector(numberOfSectionsInTableView:)]) {
sections = [dataSource numberOfSectionsInTableView:tableView];
}
if (dataSource && [dataSource respondsToSelector:@selector(tableView:numberOfRowsInSection:)]) {
for (NSInteger section = 0; section < sections; section++) {
items += [dataSource tableView:tableView numberOfRowsInSection:section];
}
}
}
// UICollectionView support
else if ([self isKindOfClass:[UICollectionView class]]) {
UICollectionView *collectionView = (UICollectionView *)self;
id <UICollectionViewDataSource> dataSource = collectionView.dataSource;
NSInteger sections = 1;
if (dataSource && [dataSource respondsToSelector:@selector(numberOfSectionsInCollectionView:)]) {
sections = [dataSource numberOfSectionsInCollectionView:collectionView];
}
if (dataSource && [dataSource respondsToSelector:@selector(collectionView:numberOfItemsInSection:)]) {
for (NSInteger section = 0; section < sections; section++) {
items += [dataSource collectionView:collectionView numberOfItemsInSection:section];
}
}
}
return items;
}
3,我也嘗試寫(xiě)過(guò)類(lèi)似控件
實(shí)現(xiàn)的思路和DZNEmptyDataSet思路基本是一致
1,添加分類(lèi)
2,運(yùn)行時(shí)攔截替換reloadata函數(shù)
3,計(jì)算datasource數(shù)量,作相應(yīng)處理。
發(fā)現(xiàn)了DZNEmptyDataSet 幾個(gè)地方可優(yōu)化的地方
1,headerView顯示過(guò)長(zhǎng)的時(shí)候可以自動(dòng)適當(dāng)調(diào)節(jié)EmptyView的frame
2,網(wǎng)絡(luò)狀態(tài)異常可以自動(dòng)顯示文本提示,不用額外添加代碼處理。
3,需要額外設(shè)置其delegate和datasource方能生效。