DZNEmptyDataSet源码

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  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  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方能生效。

你可能感兴趣的:(DZNEmptyDataSet源码)