DZNEmptyDataSet

1,445 阅读2分钟

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