DZNEmptyDataSet是一款优秀的处理数据集合为空的轻量型框架 基于 UITableView/UICollectionView 的category类,默认情况下,如果我们的的表视图是空的,屏幕上什么也不会显示,它给用户的体验不是很好。该库可以很灵活地帮我们很好地处理集合视图,然后合理美观地显示出用户信息。
1,用法 使用的方法还是很简单, 下载官方的demo一看懂了,快捷方便,设置相应代理即可
self.tableView.emptyDataSetSource = self;
self.tableView.emptyDataSetDelegate = self;
然后再根据具体的需要自定义自己App的显示特点,DZNEmptyDataSet为我们提供了丰富多种的设置方法,其中常用的方法有3个
/** 数据为空时,显示的提示标语 */
- (nullable NSAttributedString *)titleForEmptyDataSet:(UIScrollView *)scrollView;
/** 数据为空时,显示的提示显示内容 */
- (nullable NSAttributedString *)descriptionForEmptyDataSet:(UIScrollView *)scrollView;
/** 数据为空时,显示的提示显示图像 */
-
(nullable UIImage *)imageForEmptyDataSet:(UIScrollView *)scrollView; 2,实现原理 关键的意思就运用了runtime特性,替换掉UITableView 或者 UICollectionView 的reloadData 函数
// Swizzle by injecting additional implementation Method method = class_getInstanceMethod(baseClass, selector); IMP dzn_newImplementation = method_setImplementation(method, (IMP)dzn_original_implementation); 拦截该方法之后在适当的时机计算datasource的数量,如果总数量为空就像是相应的视图,否则还是按照原本的处理逻辑
-
(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,我也尝试写过类似控件 实现的思路和DZNEmptyDataSet思路基本是一致 1,添加分类 2,运行时拦截替换reloadata函数 3,计算datasource数量,作相应处理。
发现了DZNEmptyDataSet 几个地方可优化的地方 1,headerView显示过长的时候可以自动适当调节EmptyView的frame 2,网络状态异常可以自动显示文本提示,不用额外添加代码处理。 3,需要额外设置其delegate和datasource方能生效。