美文网首页
DZNEmptyDataSet源码

DZNEmptyDataSet源码

作者: tangbin583085 | 来源:发表于2018-01-06 12:03 被阅读0次

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

    相关文章

      网友评论

          本文标题:DZNEmptyDataSet源码

          本文链接:https://www.haomeiwen.com/subject/zphhnxtx.html